[pypy-commit] pypy resume-refactor: Fix the problem with gaps and start writing a test for consts
fijal
noreply at buildbot.pypy.org
Tue Jan 14 12:17:13 CET 2014
Author: Maciej Fijalkowski <fijall at gmail.com>
Branch: resume-refactor
Changeset: r68664:78ad080697be
Date: 2014-01-13 15:08 +0100
http://bitbucket.org/pypy/pypy/changeset/78ad080697be/
Log: Fix the problem with gaps and start writing a test for consts
diff --git a/rpython/jit/backend/llgraph/runner.py b/rpython/jit/backend/llgraph/runner.py
--- a/rpython/jit/backend/llgraph/runner.py
+++ b/rpython/jit/backend/llgraph/runner.py
@@ -18,14 +18,15 @@
class Position(object):
def __init__(self, pos):
+ assert pos != -1
self.pos = pos
def get_jitframe_position(self):
return self.pos
class ResumeFrame(object):
- def __init__(self, num, start_pos):
- self.registers = [None] * num
+ def __init__(self, no, start_pos):
+ self.registers = [None] * no
self.start_pos = start_pos
class LLGraphResumeBuilder(ResumeBuilder):
@@ -33,20 +34,20 @@
self.liveness = LivenessAnalyzer()
self.numbering = {}
self.framestack = []
- locs = []
+ locs = None
start_pos = 0
- for frame_pos, frame in enumerate(inputframes):
- if inputlocs is not None:
+ if inputlocs is not None:
+ locs = []
+ for frame_pos, frame in enumerate(inputframes):
self.framestack.append(ResumeFrame(len(frame), start_pos))
- for pos_in_frame, box in enumerate(frame):
- if inputlocs is not None:
+ for pos_in_frame, box in enumerate(frame):
+ if box is None:
+ continue
pos = inputlocs[frame_pos][pos_in_frame]
self.framestack[-1].registers[pos_in_frame] = box
- else:
- pos = len(self.numbering)
- self.numbering[box] = pos
- locs.append(Position(pos))
- start_pos += len(frame)
+ self.numbering[box] = pos
+ locs.append(Position(pos))
+ start_pos += 1
ResumeBuilder.__init__(self, self, frontend_liveness, descr,
inputframes, locs)
@@ -83,7 +84,10 @@
lst = []
for frame in self.framestack:
for reg in frame.registers:
- lst.append(mapping(reg))
+ if reg is None:
+ lst.append(None)
+ else:
+ lst.append(mapping(reg))
return lst
class LLTrace(object):
@@ -365,13 +369,12 @@
assert frame.forced_deadframe is None
values = []
for box in frame.force_guard_op.failargs:
- if box is not None:
- if box is not frame.current_op.result:
- value = frame.env[box]
- else:
- value = box.value # 0 or 0.0 or NULL
+ if box is None:
+ value = None
+ elif box is not frame.current_op.result:
+ value = frame.env[box]
else:
- value = None
+ value = box.value # 0 or 0.0 or NULL
values.append(value)
frame.forced_deadframe = LLDeadFrame(
_getdescr(frame.force_guard_op), values)
@@ -777,11 +780,14 @@
i += 1
def do_renaming(self, newargs, newvalues):
- assert len(newargs) == len(newvalues)
self.env = {}
self.framecontent = {}
- for new, newvalue in zip(newargs, newvalues):
- self.setenv(new, newvalue)
+ i = 0
+ for value in newvalues:
+ if value is None:
+ continue
+ self.setenv(newargs[i], value)
+ i += 1
# -----------------------------------------------------
@@ -790,10 +796,10 @@
for i in range(len(self.current_op.failargs)):
arg = self.current_op.failargs[i]
if arg is None:
- values.append(None)
+ value = None
else:
value = self.env[arg]
- values.append(value)
+ values.append(value)
if hasattr(descr, '_llgraph_bridge'):
target = (descr._llgraph_bridge, -1)
raise Jump(target, values)
diff --git a/rpython/jit/backend/llsupport/assembler.py b/rpython/jit/backend/llsupport/assembler.py
--- a/rpython/jit/backend/llsupport/assembler.py
+++ b/rpython/jit/backend/llsupport/assembler.py
@@ -111,35 +111,32 @@
return r
def rebuild_faillocs_from_descr(self, descr, inputframes, loc_positions):
- lgt = 0
- for frame in inputframes:
- lgt += len(frame)
- locs = [None] * lgt
+ locs = []
GPR_REGS = len(self.cpu.gen_regs)
XMM_REGS = len(self.cpu.float_regs)
if self.cpu.IS_64_BIT:
coeff = 1
else:
coeff = 2
- locs_index = 0
for i, frame in enumerate(inputframes):
inputlocs = loc_positions[i]
assert len(inputlocs) == len(frame)
for j, item in enumerate(frame):
+ if item is None:
+ continue
pos = inputlocs[j]
if pos < GPR_REGS:
- locs[locs_index] = self.cpu.gen_regs[pos]
+ locs.append(self.cpu.gen_regs[pos])
elif pos < (GPR_REGS + XMM_REGS * coeff):
pos = (pos - GPR_REGS) // coeff
- locs[locs_index] = self.cpu.float_regs[pos]
+ locs.append(self.cpu.float_regs[pos])
else:
stack_pos = pos - self.cpu.JITFRAME_FIXED_SIZE
assert stack_pos >= 0
tp = item.type
- locs[locs_index] = self.new_stack_loc(stack_pos,
- pos * WORD, tp)
- locs_index += 1
- return locs
+ locs.append(self.new_stack_loc(stack_pos,
+ pos * WORD, tp))
+ return locs[:]
def store_info_on_descr(self, startspos, guardtok, resume_bytecode):
withfloats = guardtok.has_floats
diff --git a/rpython/jit/backend/resumebuilder.py b/rpython/jit/backend/resumebuilder.py
--- a/rpython/jit/backend/resumebuilder.py
+++ b/rpython/jit/backend/resumebuilder.py
@@ -12,7 +12,7 @@
if inputframes is not None:
for frame in inputframes:
self.frame_starts.append(self.frame_starts[-1] + len(frame))
- self.framestack.append(frame)
+ self.framestack.append(frame[:])
def enter_frame(self, pc, jitcode):
self.frame_starts.append(self.frame_starts[-1] + jitcode.num_regs())
@@ -64,11 +64,14 @@
i = 0
for frame_pos, frame in enumerate(inputframes):
for pos_in_frame, box in enumerate(frame):
- loc_pos = inputlocs[i].get_jitframe_position()
+ if box is None:
+ loc_pos = -1
+ else:
+ loc_pos = inputlocs[i].get_jitframe_position()
+ i += 1
+ self.frontend_pos[box] = (ConstInt(frame_pos),
+ ConstInt(pos_in_frame))
self.current_attachment[box] = loc_pos
- self.frontend_pos[box] = (ConstInt(frame_pos),
- ConstInt(pos_in_frame))
- i += 1
def process(self, op):
if op.getopnum() == rop.RESUME_PUT:
@@ -131,12 +134,16 @@
def flatten(inputframes):
count = 0
for frame in inputframes:
- count += len(frame)
+ for x in frame:
+ if x is not None:
+ count += 1
inputargs = [None] * count
- i = 0
+ pos = 0
for frame in inputframes:
- inputargs[i:i + len(frame)] = frame
- i += len(frame)
+ for item in frame:
+ if item is not None:
+ inputargs[pos] = item
+ pos += 1
return inputargs
diff --git a/rpython/jit/backend/test/runner_test.py b/rpython/jit/backend/test/runner_test.py
--- a/rpython/jit/backend/test/runner_test.py
+++ b/rpython/jit/backend/test/runner_test.py
@@ -259,6 +259,52 @@
assert self.cpu.tracker.total_compiled_bridges == 1
return looptoken
+ def test_compile_bridge_with_holes(self):
+ i0 = BoxInt()
+ i1 = BoxInt()
+ i2 = BoxInt()
+ i3 = BoxInt()
+ faildescr1 = BasicFailDescr(1)
+ faildescr2 = BasicFailDescr(2)
+ looptoken = JitCellToken()
+ targettoken = TargetToken()
+ jitcode = JitCode('name')
+ jitcode.setup(num_regs_i=3, num_regs_r=0, num_regs_f=0)
+ operations = [
+ ResOperation(rop.ENTER_FRAME, [ConstInt(-1)], None, descr=jitcode),
+ ResOperation(rop.INT_SUB, [i3, ConstInt(42)], i0),
+ ResOperation(rop.LABEL, [i0], None, descr=targettoken),
+ ResOperation(rop.INT_ADD, [i0, ConstInt(1)], i1),
+ ResOperation(rop.INT_LE, [i1, ConstInt(9)], i2),
+ ResOperation(rop.RESUME_PUT, [i1, ConstInt(0), ConstInt(1)],
+ None),
+ ResOperation(rop.GUARD_TRUE, [i2], None, descr=faildescr1),
+ ResOperation(rop.JUMP, [i1], None, descr=targettoken),
+ ]
+ inputargs = [i3]
+ self.cpu.compile_loop(None, inputargs, operations, looptoken)
+
+ i1b = BoxInt()
+ i3 = BoxInt()
+ bridge = [
+ ResOperation(rop.INT_LE, [i1b, ConstInt(19)], i3),
+ ResOperation(rop.RESUME_PUT, [i3, ConstInt(0), ConstInt(2)],
+ None),
+ ResOperation(rop.GUARD_TRUE, [i3], None, descr=faildescr2),
+ ResOperation(rop.JUMP, [i1b], None, descr=targettoken),
+ ]
+
+ locs = rebuild_locs_from_resumedata(faildescr1)
+ self.cpu.compile_bridge(None, faildescr1, [[None, i1b, None]],
+ locs, bridge, looptoken)
+
+ deadframe = self.cpu.execute_token(looptoken, 2)
+ fail = self.cpu.get_latest_descr(deadframe)
+ assert fail.identifier == 2
+ locs = rebuild_locs_from_resumedata(fail)
+ res = self.cpu.get_int_value(deadframe, locs[0][1])
+ assert res == 20
+
def test_compile_big_bridge_out_of_small_loop(self):
jitcode = JitCode("name")
jitcode.setup(num_regs_i=1, num_regs_r=0, num_regs_f=0)
diff --git a/rpython/jit/backend/x86/regalloc.py b/rpython/jit/backend/x86/regalloc.py
--- a/rpython/jit/backend/x86/regalloc.py
+++ b/rpython/jit/backend/x86/regalloc.py
@@ -238,6 +238,7 @@
used = {}
i = 0
inputargs = flatten(inputframes)
+ assert len(inputargs) == len(locs)
for loc in locs:
if loc is None: # xxx bit kludgy
loc = ebp
diff --git a/rpython/jit/codewriter/codewriter.py b/rpython/jit/codewriter/codewriter.py
--- a/rpython/jit/codewriter/codewriter.py
+++ b/rpython/jit/codewriter/codewriter.py
@@ -13,7 +13,7 @@
class CodeWriter(object):
callcontrol = None # for tests
- debug = False
+ debug = True
def __init__(self, cpu=None, jitdrivers_sd=[]):
self.cpu = cpu
diff --git a/rpython/jit/metainterp/compile.py b/rpython/jit/metainterp/compile.py
--- a/rpython/jit/metainterp/compile.py
+++ b/rpython/jit/metainterp/compile.py
@@ -16,7 +16,7 @@
from rpython.jit.metainterp.inliner import Inliner
from rpython.jit.metainterp.resume import NUMBERING, PENDINGFIELDSP, ResumeDataDirectReader
from rpython.jit.codewriter import heaptracker, longlong
-
+from rpython.jit.backend.resumebuilder import flatten
def giveup():
from rpython.jit.metainterp.pyjitpl import SwitchToBlackhole
@@ -306,12 +306,14 @@
inputargs, operations, looptoken,
log=log, name=name)
-def do_compile_bridge(metainterp_sd, faildescr, inputargs, operations,
- original_loop_token, log=True):
- metainterp_sd.logger_ops.log_bridge(inputargs, operations, "compiling")
+def do_compile_bridge(metainterp_sd, faildescr, inputframes,
+ inputlocs, operations, original_loop_token, log=True):
+ metainterp_sd.logger_ops.log_bridge(flatten(inputframes), operations,
+ "compiling")
assert isinstance(faildescr, AbstractFailDescr)
return metainterp_sd.cpu.compile_bridge(metainterp_sd.logger_ops,
- faildescr, inputargs, operations,
+ faildescr, inputframes,
+ inputlocs, operations,
original_loop_token, log=log)
def send_loop_to_backend(greenkey, jitdriver_sd, metainterp_sd, loop, type):
@@ -367,11 +369,11 @@
if metainterp_sd.warmrunnerdesc is not None: # for tests
metainterp_sd.warmrunnerdesc.memory_manager.keep_loop_alive(original_jitcell_token)
-def send_bridge_to_backend(jitdriver_sd, metainterp_sd, faildescr, inputargs,
- operations, original_loop_token):
+def send_bridge_to_backend(jitdriver_sd, metainterp_sd, faildescr, inputframes,
+ inputlocs, operations, original_loop_token):
if not we_are_translated():
show_procedures(metainterp_sd)
- seen = dict.fromkeys(inputargs)
+ seen = dict.fromkeys(flatten(inputframes))
TreeLoop.check_consistency_of_branch(operations, seen)
if metainterp_sd.warmrunnerdesc is not None:
hooks = metainterp_sd.warmrunnerdesc.hooks
@@ -386,8 +388,8 @@
metainterp_sd.profiler.start_backend()
debug_start("jit-backend")
try:
- asminfo = do_compile_bridge(metainterp_sd, faildescr, inputargs,
- operations,
+ asminfo = do_compile_bridge(metainterp_sd, faildescr, inputframes,
+ inputlocs, operations,
original_loop_token)
finally:
debug_stop("jit-backend")
@@ -403,8 +405,8 @@
ops_offset = asminfo.ops_offset
else:
ops_offset = None
- metainterp_sd.logger_ops.log_bridge(inputargs, operations, None, faildescr,
- ops_offset)
+ metainterp_sd.logger_ops.log_bridge(flatten(inputframes), operations,
+ None, faildescr, ops_offset)
#
#if metainterp_sd.warmrunnerdesc is not None: # for tests
# metainterp_sd.warmrunnerdesc.memory_manager.keep_loop_alive(
@@ -612,12 +614,14 @@
# to the corresponding guard_op and compile from there
assert metainterp.resumekey_original_loop_token is not None
new_loop.original_jitcell_token = metainterp.resumekey_original_loop_token
- inputargs = metainterp.history.inputargs
+ inputframes = metainterp.history.inputframes
+ inputlocs = metainterp.history.inputlocs
if not we_are_translated():
self._debug_suboperations = new_loop.operations
propagate_original_jitcell_token(new_loop)
send_bridge_to_backend(metainterp.jitdriver_sd, metainterp.staticdata,
- self, inputargs, new_loop.operations,
+ self, inputframes, inputlocs,
+ new_loop.operations,
new_loop.original_jitcell_token)
class ResumeGuardNotInvalidated(ResumeGuardDescr):
@@ -804,7 +808,8 @@
# Attempt to use optimize_bridge(). This may return None in case
# it does not work -- i.e. none of the existing old_loop_tokens match.
new_trace = create_empty_loop(metainterp)
- new_trace.inputargs = metainterp.history.inputargs[:]
+ new_trace.inputframes = metainterp.history.inputframes[:]
+ new_trace.inputlocs = metainterp.history.inputlocs[:]
# clone ops, as optimize_bridge can mutate the ops
new_trace.operations = [op.clone() for op in metainterp.history.operations]
diff --git a/rpython/jit/metainterp/optimizeopt/unroll.py b/rpython/jit/metainterp/optimizeopt/unroll.py
--- a/rpython/jit/metainterp/optimizeopt/unroll.py
+++ b/rpython/jit/metainterp/optimizeopt/unroll.py
@@ -167,7 +167,7 @@
jump_args = [self.getvalue(a).get_key_box() for a in original_jump_args]
assert self.optimizer.loop.resume_at_jump_descr
- resume_at_jump_descr = self.optimizer.loop.resume_at_jump_descr.clone_if_mutable()
+ resume_at_jump_descr = self.optimizer.loop.resume_at_jump_descr
assert isinstance(resume_at_jump_descr, ResumeGuardDescr)
resume_at_jump_descr.rd_snapshot = self.fix_snapshot(jump_args, resume_at_jump_descr.rd_snapshot)
@@ -421,7 +421,7 @@
if op.is_guard():
op = op.clone()
op.setfailargs(None)
- descr = target_token.resume_at_jump_descr.clone_if_mutable()
+ descr = target_token.resume_at_jump_descr
op.setdescr(descr)
short[i] = op
@@ -444,7 +444,7 @@
if op.result and op.result in self.short_boxes.assumed_classes:
target_token.assumed_classes[newop.result] = self.short_boxes.assumed_classes[op.result]
short[i] = newop
- target_token.resume_at_jump_descr = target_token.resume_at_jump_descr.clone_if_mutable()
+ target_token.resume_at_jump_descr = target_token.resume_at_jump_descr
inliner.inline_descr_inplace(target_token.resume_at_jump_descr)
# Forget the values to allow them to be freed
@@ -489,7 +489,7 @@
if not isinstance(a, Const) and a not in self.short_seen:
self.add_op_to_short(self.short_boxes.producer(a), emit, guards_needed)
if op.is_guard():
- descr = self.short_resume_at_jump_descr.clone_if_mutable()
+ descr = self.short_resume_at_jump_descr
op.setdescr(descr)
if guards_needed and self.short_boxes.has_producer(op.result):
@@ -588,7 +588,7 @@
for guard in extra_guards:
if guard.is_guard():
- descr = target.resume_at_jump_descr.clone_if_mutable()
+ descr = target.resume_at_jump_descr
inliner.inline_descr_inplace(descr)
guard.setdescr(descr)
self.optimizer.send_extra_operation(guard)
diff --git a/rpython/jit/metainterp/pyjitpl.py b/rpython/jit/metainterp/pyjitpl.py
--- a/rpython/jit/metainterp/pyjitpl.py
+++ b/rpython/jit/metainterp/pyjitpl.py
@@ -1698,13 +1698,14 @@
def is_main_jitcode(self, jitcode):
return self.jitdriver_sd is not None and jitcode is self.jitdriver_sd.mainjitcode
- def newframe(self, jitcode, greenkey=None):
+ def newframe(self, jitcode, greenkey=None, record_resume=True):
if self.framestack:
pc = self.framestack[-1].pc
else:
pc = -1
- self.history.record(rop.ENTER_FRAME, [ConstInt(pc)], None,
- descr=jitcode)
+ if record_resume:
+ self.history.record(rop.ENTER_FRAME, [ConstInt(pc)], None,
+ descr=jitcode)
if jitcode.is_portal:
self.portal_call_depth += 1
self.call_ids.append(self.current_call_id)
@@ -2409,9 +2410,8 @@
try:
self.portal_call_depth = -1 # always one portal around
self.history = history.History()
- self.rebuild_state_after_failure(resumedescr, deadframe)
- xxx
- self.history.inputargs = [box for box in inputargs_and_holes if box]
+ state = self.rebuild_state_after_failure(resumedescr, deadframe)
+ self.history.inputframes, self.history.inputlocs = state
finally:
rstack._stack_criticalcode_stop()
@@ -2531,10 +2531,10 @@
vinfo = self.jitdriver_sd.virtualizable_info
ginfo = self.jitdriver_sd.greenfield_info
self.framestack = []
- inputframes = resume2.rebuild_from_resumedata(self, deadframe,
- resumedescr)
- virtualizable_boxes = None
- virtualref_boxes = None
+ inputlocs = resume2.rebuild_from_resumedata(self, deadframe,
+ resumedescr)
+ virtualizable_boxes = []
+ virtualref_boxes = []
#
# virtual refs: make the vrefs point to the freshly allocated virtuals
self.virtualref_boxes = virtualref_boxes
@@ -2565,7 +2565,7 @@
else:
assert not virtualizable_boxes
#
- return inputframes
+ return inputlocs
def check_synchronized_virtualizable(self):
if not we_are_translated():
diff --git a/rpython/jit/metainterp/resume2.py b/rpython/jit/metainterp/resume2.py
--- a/rpython/jit/metainterp/resume2.py
+++ b/rpython/jit/metainterp/resume2.py
@@ -132,29 +132,35 @@
pos))
def finish(self):
+ res = []
for frame in self.framestack:
jitcode = frame.jitcode
- miframe = self.metainterp.newframe(jitcode)
+ res.append([None] * jitcode.num_regs())
+ miframe = self.metainterp.newframe(jitcode, record_resume=False)
miframe.pc = frame.pc
pos = 0
for i in range(jitcode.num_regs_i()):
jitframe_pos = frame.registers[pos]
- if jitframe_pos == -1:
- continue
- miframe.registers_i[i] = self.get_int_box(jitframe_pos)
+ if jitframe_pos != -1:
+ box = self.get_int_box(jitframe_pos)
+ miframe.registers_i[i] = box
+ res[-1][pos] = box
pos += 1
for i in range(jitcode.num_regs_r()):
jitframe_pos = frame.registers[pos]
- if jitframe_pos == -1:
- continue
- miframe.registers_r[i] = self.get_ref_box(jitframe_pos)
+ if jitframe_pos != -1:
+ box = self.get_int_box(jitframe_pos)
+ res[-1][pos] = box
+ miframe.registers_r[i] = box
pos += 1
for i in range(jitcode.num_regs_f()):
jitframe_pos = frame.registers[pos]
- if jitframe_pos == -1:
- continue
- miframe.registers_f[i] = self.get_float_box(jitframe_pos)
+ if jitframe_pos != -1:
+ box = self.get_int_box(jitframe_pos)
+ res[-1][pos] = box
+ miframe.registers_f[i] = box
pos += 1
+ return res, [f.registers for f in self.framestack]
def rebuild_from_resumedata(metainterp, deadframe, faildescr):
return BoxResumeReader(metainterp, deadframe).rebuild(faildescr)
diff --git a/rpython/jit/metainterp/test/test_resume2.py b/rpython/jit/metainterp/test/test_resume2.py
--- a/rpython/jit/metainterp/test/test_resume2.py
+++ b/rpython/jit/metainterp/test/test_resume2.py
@@ -21,7 +21,7 @@
self.registers_f = [None] * jitcode.num_regs_f()
def num_nonempty_regs(self):
- return len([i for i in self.registers_i if i.getint() != 2])
+ return len([i for i in self.registers_i if i is not None])
def dump_registers(self, lst, backend_values):
lst += [backend_values[x] for x in self.registers_i]
@@ -33,7 +33,7 @@
self.cpu = MockCPU()
self.framestack = []
- def newframe(self, jitcode):
+ def newframe(self, jitcode, record_resume=False):
f = Frame(jitcode)
self.framestack.append(f)
return f
@@ -94,7 +94,7 @@
descr = Descr()
descr.rd_resume_bytecode = ResumeBytecode(resume_loop.operations)
descr.rd_bytecode_position = 5
- rebuild_from_resumedata(metainterp, "myframe", descr)
+ state = rebuild_from_resumedata(metainterp, "myframe", descr)
assert len(metainterp.framestack) == 2
f = metainterp.framestack[-1]
f2 = metainterp.framestack[0]
@@ -177,3 +177,6 @@
descr.rd_bytecode_position = 5
locs = rebuild_locs_from_resumedata(descr)
assert locs == [[8, 11], [12]]
+
+ def test_resume_put_const(self):
+ xxx
More information about the pypy-commit
mailing list