Author: Maciej Fijalkowski <fij...@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 _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit