Author: Hakan Ardo <ha...@debian.org> Branch: jit-targets Changeset: r49751:aeb52741cfeb Date: 2011-11-24 20:12 +0100 http://bitbucket.org/pypy/pypy/changeset/aeb52741cfeb/
Log: hg merge diff --git a/pypy/jit/backend/llsupport/regalloc.py b/pypy/jit/backend/llsupport/regalloc.py --- a/pypy/jit/backend/llsupport/regalloc.py +++ b/pypy/jit/backend/llsupport/regalloc.py @@ -37,6 +37,9 @@ self.frame_depth += size return newloc + def forget_frame_allocation(self, box): + self.frame_bindings.pop(box, None) + def reserve_location_in_frame(self, size): frame_depth = self.frame_depth self.frame_depth += size diff --git a/pypy/jit/backend/test/runner_test.py b/pypy/jit/backend/test/runner_test.py --- a/pypy/jit/backend/test/runner_test.py +++ b/pypy/jit/backend/test/runner_test.py @@ -3033,7 +3033,91 @@ res = self.cpu.get_latest_value_int(0) assert res == -10 - + def test_compile_bridge_with_target(self): + # This test creates a loopy piece of code in a bridge, and builds another + # unrelated loop that ends in a jump directly to this loopy bit of code. + # It catches a case in which we underestimate the needed frame_depth across + # the cross-loop JUMP, because we estimate it based on the frame_depth stored + # in the original loop. + i0 = BoxInt() + i1 = BoxInt() + looptoken1 = JitCellToken() + targettoken1 = TargetToken() + faildescr1 = BasicFailDescr(2) + inputargs = [i0] + operations = [ + ResOperation(rop.INT_LE, [i0, ConstInt(1)], i1), + ResOperation(rop.GUARD_TRUE, [i1], None, descr=faildescr1), + ResOperation(rop.FINISH, [i0], None, descr=BasicFailDescr(1234)), + ] + operations[1].setfailargs([i0]) + self.cpu.compile_loop(inputargs, operations, looptoken1) + + def func(a, b, c, d, e, f, g, h, i): + assert a + 2 == b + assert a + 4 == c + assert a + 6 == d + assert a + 8 == e + assert a + 10 == f + assert a + 12 == g + assert a + 14 == h + assert a + 16 == i + FPTR = self.Ptr(self.FuncType([lltype.Signed]*9, lltype.Void)) + func_ptr = llhelper(FPTR, func) + cpu = self.cpu + calldescr = cpu.calldescrof(deref(FPTR), (lltype.Signed,)*9, lltype.Void, + EffectInfo.MOST_GENERAL) + funcbox = self.get_funcbox(cpu, func_ptr) + + i0 = BoxInt(); i1 = BoxInt(); i2 = BoxInt(); i3 = BoxInt(); i4 = BoxInt() + i5 = BoxInt(); i6 = BoxInt(); i7 = BoxInt(); i8 = BoxInt(); i9 = BoxInt() + i10 = BoxInt(); i11 = BoxInt(); i12 = BoxInt(); i13 = BoxInt(); i14 = BoxInt() + i15 = BoxInt(); i16 = BoxInt(); i17 = BoxInt(); i18 = BoxInt(); i19 = BoxInt() + i20 = BoxInt() + inputargs = [i0] + operations = [ + ResOperation(rop.LABEL, [i0], None, descr=targettoken1), + ResOperation(rop.INT_ADD, [i0, ConstInt(1)], i1), + ResOperation(rop.INT_ADD, [i1, ConstInt(1)], i2), + ResOperation(rop.INT_ADD, [i2, ConstInt(1)], i3), + ResOperation(rop.INT_ADD, [i3, ConstInt(1)], i4), + ResOperation(rop.INT_ADD, [i4, ConstInt(1)], i5), + ResOperation(rop.INT_ADD, [i5, ConstInt(1)], i6), + ResOperation(rop.INT_ADD, [i6, ConstInt(1)], i7), + ResOperation(rop.INT_ADD, [i7, ConstInt(1)], i8), + ResOperation(rop.INT_ADD, [i8, ConstInt(1)], i9), + ResOperation(rop.INT_ADD, [i9, ConstInt(1)], i10), + ResOperation(rop.INT_ADD, [i10, ConstInt(1)], i11), + ResOperation(rop.INT_ADD, [i11, ConstInt(1)], i12), + ResOperation(rop.INT_ADD, [i12, ConstInt(1)], i13), + ResOperation(rop.INT_ADD, [i13, ConstInt(1)], i14), + ResOperation(rop.INT_ADD, [i14, ConstInt(1)], i15), + ResOperation(rop.INT_ADD, [i15, ConstInt(1)], i16), + ResOperation(rop.INT_ADD, [i16, ConstInt(1)], i17), + ResOperation(rop.INT_ADD, [i17, ConstInt(1)], i18), + ResOperation(rop.INT_ADD, [i18, ConstInt(1)], i19), + ResOperation(rop.CALL, [funcbox, i2, i4, i6, i8, i10, i12, i14, i16, i18], + None, descr=calldescr), + ResOperation(rop.CALL, [funcbox, i2, i4, i6, i8, i10, i12, i14, i16, i18], + None, descr=calldescr), + ResOperation(rop.INT_LT, [i19, ConstInt(100)], i20), + ResOperation(rop.GUARD_TRUE, [i20], None, descr=BasicFailDescr(42)), + ResOperation(rop.JUMP, [i19], None, descr=targettoken1), + ] + operations[-2].setfailargs([]) + self.cpu.compile_bridge(faildescr1, inputargs, operations, looptoken1) + + looptoken2 = JitCellToken() + inputargs = [] + operations = [ + ResOperation(rop.JUMP, [ConstInt(0)], None, descr=targettoken1), + ] + self.cpu.compile_loop(inputargs, operations, looptoken2) + + fail = self.cpu.execute_token(looptoken2) + assert fail.identifier == 42 + + class OOtypeBackendTest(BaseBackendTest): type_system = 'ootype' diff --git a/pypy/jit/backend/test/test_random.py b/pypy/jit/backend/test/test_random.py --- a/pypy/jit/backend/test/test_random.py +++ b/pypy/jit/backend/test/test_random.py @@ -525,31 +525,53 @@ startvars.append(BoxFloat(r.random_float_storage())) else: startvars.append(BoxInt(r.random_integer())) + allow_delay = True + else: + allow_delay = False assert len(dict.fromkeys(startvars)) == len(startvars) self.startvars = startvars self.prebuilt_ptr_consts = [] self.r = r - self.build_random_loop(cpu, builder_factory, r, startvars) + self.build_random_loop(cpu, builder_factory, r, startvars, allow_delay) - def build_random_loop(self, cpu, builder_factory, r, startvars): + def build_random_loop(self, cpu, builder_factory, r, startvars, allow_delay): loop = TreeLoop('test_random_function') loop.inputargs = startvars[:] loop.operations = [] loop._jitcelltoken = JitCellToken() - loop._targettoken = TargetToken() - loop.operations.append(ResOperation(rop.LABEL, loop.inputargs, None, - loop._targettoken)) builder = builder_factory(cpu, loop, startvars[:]) - self.generate_ops(builder, r, loop, startvars) + if allow_delay: + needs_a_label = True + else: + self.insert_label(loop, 0, r) + needs_a_label = False + self.generate_ops(builder, r, loop, startvars, needs_a_label=needs_a_label) self.builder = builder self.loop = loop + dump(loop) cpu.compile_loop(loop.inputargs, loop.operations, loop._jitcelltoken) - def generate_ops(self, builder, r, loop, startvars): + def insert_label(self, loop, position, r): + assert not hasattr(loop, '_targettoken') + for i in range(position): + op = loop.operations[i] + if (not op.has_no_side_effect() + or not isinstance(op.result, (BoxInt, BoxFloat))): + position = i + break # cannot move the LABEL later + randompos = r.randrange(0, len(self.startvars)+1) + self.startvars.insert(randompos, op.result) + loop._targettoken = TargetToken() + loop.operations.insert(position, ResOperation(rop.LABEL, self.startvars, None, + loop._targettoken)) + + def generate_ops(self, builder, r, loop, startvars, needs_a_label=False): block_length = pytest.config.option.block_length + istart = 0 for i in range(block_length): + istart = len(loop.operations) try: op = r.choice(builder.OPERATIONS) op.filter(builder) @@ -558,6 +580,12 @@ pass if builder.should_fail_by is not None: break + if needs_a_label and r.random() < 0.2: + self.insert_label(loop, istart, r) + needs_a_label = False + if needs_a_label: + self.insert_label(loop, istart, r) + endvars = [] used_later = {} for op in loop.operations: @@ -583,6 +611,17 @@ if pytest.config.option.output: builder.print_loop() + def runjitcelltoken(self): + if self.startvars == self.loop.inputargs: + return self.loop._jitcelltoken + if not hasattr(self, '_initialjumploop_celltoken'): + self._initialjumploop_celltoken = JitCellToken() + self.cpu.compile_loop(self.startvars[:], + [ResOperation(rop.JUMP, self.startvars[:], None, + descr=self.loop._targettoken)], + self._initialjumploop_celltoken) + return self._initialjumploop_celltoken + def get_fail_args(self): if self.should_fail_by.is_guard(): assert self.should_fail_by.getfailargs() is not None @@ -617,7 +656,7 @@ cpu.set_future_value_float(i, box.value) else: raise NotImplementedError(box) - fail = cpu.execute_token(self.loop._jitcelltoken) + fail = cpu.execute_token(self.runjitcelltoken()) assert fail is self.should_fail_by.getdescr() for i, v in enumerate(self.get_fail_args()): if isinstance(v, (BoxFloat, ConstFloat)): @@ -685,6 +724,7 @@ args = [x.clonebox() for x in subset] rl = RandomLoop(self.builder.cpu, self.builder.fork, r, args) + dump(rl.loop) self.cpu.compile_loop(rl.loop.inputargs, rl.loop.operations, rl.loop._jitcelltoken) # done @@ -702,11 +742,19 @@ self.dont_generate_more = True if r.random() < .05: return False + dump(subloop) self.builder.cpu.compile_bridge(fail_descr, fail_args, subloop.operations, self.loop._jitcelltoken) return True +def dump(loop): + print >> sys.stderr, loop + if hasattr(loop, 'inputargs'): + print >> sys.stderr, '\t', loop.inputargs + for op in loop.operations: + print >> sys.stderr, '\t', op + def check_random_function(cpu, BuilderClass, r, num=None, max=None): loop = RandomLoop(cpu, BuilderClass, r) while True: diff --git a/pypy/jit/backend/x86/assembler.py b/pypy/jit/backend/x86/assembler.py --- a/pypy/jit/backend/x86/assembler.py +++ b/pypy/jit/backend/x86/assembler.py @@ -546,6 +546,8 @@ self.patch_jump_for_descr(faildescr, rawstart) ops_offset = self.mc.ops_offset self.fixup_target_tokens(rawstart) + self.current_clt.frame_depth = max(self.current_clt.frame_depth, frame_depth) + self.current_clt.param_depth = max(self.current_clt.param_depth, param_depth) self.teardown() # oprofile support if self.cpu.profile_agent is not None: diff --git a/pypy/jit/backend/x86/regalloc.py b/pypy/jit/backend/x86/regalloc.py --- a/pypy/jit/backend/x86/regalloc.py +++ b/pypy/jit/backend/x86/regalloc.py @@ -1412,17 +1412,38 @@ arg = inputargs[i] assert not isinstance(arg, Const) loc = self.loc(arg) + if loc is ebp: + assert 0, "XXX move it away from ebp" assert not (loc is tmpreg or loc is xmmtmp) if arg.type == FLOAT: floatlocs[i] = loc else: nonfloatlocs[i] = loc + if isinstance(loc, RegLoc): + self.fm.forget_frame_allocation(arg) descr._x86_arglocs = nonfloatlocs, floatlocs descr._x86_loop_code = self.assembler.mc.get_relative_pos() descr._x86_clt = self.assembler.current_clt self.assembler.target_tokens_currently_compiling[descr] = None self.possibly_free_vars_for_op(op) +## from pypy.rpython.annlowlevel import llhelper +## def fn(addr): +## print '...label:', hex(addr), nonfloatlocs +## FUNC = lltype.Ptr(lltype.FuncType([lltype.Signed], lltype.Void)) +## ll_disp = llhelper(FUNC, fn) +## faddr = rffi.cast(lltype.Signed, ll_disp) +## for i in range(16): +## self.assembler.mc.PUSH_r(i) +## self.assembler.mc.CALL_l(0) +## self.assembler.mc.POP(edi) +## self.assembler.mc.MOV(r11, imm(faddr)) +## self.assembler.mc.CALL(r11) +## for i in range(15, -1, -1): +## if i == esp.value: +## i -= 1 +## self.assembler.mc.POP_r(i) + def not_implemented_op(self, op): not_implemented("not implemented operation: %s" % op.getopname()) diff --git a/pypy/jit/backend/x86/test/test_recompilation.py b/pypy/jit/backend/x86/test/test_recompilation.py --- a/pypy/jit/backend/x86/test/test_recompilation.py +++ b/pypy/jit/backend/x86/test/test_recompilation.py @@ -34,8 +34,8 @@ jump(i1, descr=targettoken) ''' loop = self.interpret(ops, [0]) - previous = loop.token._x86_frame_depth - assert loop.token._x86_param_depth == 0 + previous = loop._jitcelltoken.compiled_loop_token.frame_depth + assert loop._jitcelltoken.compiled_loop_token.param_depth == 0 assert self.getint(0) == 20 ops = ''' [i1] @@ -115,8 +115,8 @@ ''' bridge = self.attach_bridge(ops, loop, 6) guard_op = loop.operations[6] - loop_frame_depth = loop.token._x86_frame_depth - assert loop.token._x86_param_depth == 0 + loop_frame_depth = loop._jitcelltoken.compiled_loop_token.frame_depth + assert loop._jitcelltoken.compiled_loop_token.param_depth == 0 # XXX: Maybe add enough ops to force stack on 64-bit as well? if IS_X86_32: assert guard_op.getdescr()._x86_bridge_frame_depth > loop_frame_depth _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit