def test_jump_target_other(self): looptoken = JitCellToken() looptoken.I_am_a_descr = True # for the mock case x = ''' [] jump(descr=looptoken) ''' loop = self.parse(x, namespace=locals()) assert loop.operations[0].getdescr() is looptoken
def optimize_bridge(self, loops, bridge, expected, expected_target='Loop', **boxvalues): if isinstance(loops, str): loops = (loops, ) loops = [self.parse(loop) for loop in loops] bridge = self.parse(bridge) for loop in loops: loop.preamble = self.unroll_and_optimize(loop) preamble = loops[0].preamble token = JitCellToken() token.target_tokens = [l.operations[0].getdescr() for l in [preamble] + loops] boxes = {} for b in bridge.inputargs + [op.result for op in bridge.operations]: boxes[str(b)] = b for b, v in boxvalues.items(): boxes[b].value = v bridge.operations[-1].setdescr(token) self._do_optimize_bridge(bridge, None) if bridge.operations[-1].getopnum() == rop.LABEL: assert expected == 'RETRACE' return print '\n'.join([str(o) for o in bridge.operations]) expected = self.parse(expected) self.assert_equal(bridge, expected) if expected_target == 'Preamble': assert bridge.operations[-1].getdescr() is preamble.operations[0].getdescr() elif expected_target == 'Loop': assert len(loops) == 1 assert bridge.operations[-1].getdescr() is loops[0].operations[0].getdescr() elif expected_target.startswith('Loop'): n = int(expected_target[4:]) assert bridge.operations[-1].getdescr() is loops[n].operations[0].getdescr() else: assert False
def unroll_and_optimize(self, loop, call_pure_results=None): operations = loop.operations jumpop = operations[-1] assert jumpop.getopnum() == rop.JUMP inputargs = loop.inputargs jump_args = jumpop.getarglist()[:] operations = operations[:-1] cloned_operations = [op.clone() for op in operations] preamble = TreeLoop('preamble') preamble.inputargs = inputargs preamble.resume_at_jump_descr = FakeDescrWithSnapshot() token = JitCellToken() preamble.operations = [ResOperation(rop.LABEL, inputargs, None, descr=TargetToken(token))] + \ operations + \ [ResOperation(rop.LABEL, jump_args, None, descr=token)] self._do_optimize_loop(preamble, call_pure_results) assert preamble.operations[-1].getopnum() == rop.LABEL inliner = Inliner(inputargs, jump_args) loop.resume_at_jump_descr = preamble.resume_at_jump_descr loop.operations = [preamble.operations[-1]] + \ [inliner.inline_op(op, clone=False) for op in cloned_operations] + \ [ResOperation(rop.JUMP, [inliner.inline_arg(a) for a in jump_args], None, descr=token)] #[inliner.inline_op(jumpop)] assert loop.operations[-1].getopnum() == rop.JUMP assert loop.operations[0].getopnum() == rop.LABEL loop.inputargs = loop.operations[0].getarglist() self._do_optimize_loop(loop, call_pure_results) extra_same_as = [] while loop.operations[0].getopnum() != rop.LABEL: extra_same_as.append(loop.operations[0]) del loop.operations[0] # Hack to prevent random order of same_as ops extra_same_as.sort( key=lambda op: str(preamble.operations).find(str(op.getarg(0)))) for op in extra_same_as: preamble.operations.insert(-1, op) return preamble
def test_compile_bridge_check_profile_info(self): py.test.skip("does not work, reinvestigate") class FakeProfileAgent(object): def __init__(self): self.functions = [] def native_code_written(self, name, address, size): self.functions.append((name, address, size)) self.cpu.profile_agent = agent = FakeProfileAgent() i0 = BoxInt() i1 = BoxInt() i2 = BoxInt() targettoken = TargetToken() faildescr1 = BasicFailDescr(1) faildescr2 = BasicFailDescr(2) looptoken = JitCellToken() looptoken.number = 17 class FakeString(object): def __init__(self, val): self.val = val def _get_str(self): return self.val operations = [ ResOperation(rop.LABEL, [i0], None, descr=targettoken), ResOperation(rop.DEBUG_MERGE_POINT, [FakeString("hello"), 0], None), ResOperation(rop.INT_ADD, [i0, ConstInt(1)], i1), ResOperation(rop.INT_LE, [i1, ConstInt(9)], i2), ResOperation(rop.GUARD_TRUE, [i2], None, descr=faildescr1), ResOperation(rop.JUMP, [i1], None, descr=targettoken), ] inputargs = [i0] operations[-2].setfailargs([i1]) self.cpu.compile_loop(inputargs, operations, looptoken) name, loopaddress, loopsize = agent.functions[0] assert name == "Loop # 17: hello (loop counter 0)" assert loopaddress <= looptoken._x86_loop_code assert loopsize >= 40 # randomish number i1b = BoxInt() i3 = BoxInt() bridge = [ ResOperation(rop.INT_LE, [i1b, ConstInt(19)], i3), ResOperation(rop.GUARD_TRUE, [i3], None, descr=faildescr2), ResOperation(rop.DEBUG_MERGE_POINT, [FakeString("bye"), 0], None), ResOperation(rop.JUMP, [i1b], None, descr=targettoken), ] bridge[1].setfailargs([i1b]) self.cpu.compile_bridge(faildescr1, [i1b], bridge, looptoken) name, address, size = agent.functions[1] assert name == "Bridge # 0: bye (loop counter 1)" # Would be exactly ==, but there are some guard failure recovery # stubs in-between assert address >= loopaddress + loopsize assert size >= 10 # randomish number fail = self.cpu.execute_token(looptoken, 2) assert fail.identifier == 2 res = self.cpu.get_latest_value_int(0) assert res == 20
def make_jitcell_token(jitdriver_sd): jitcell_token = JitCellToken() jitcell_token.outermost_jitdriver_sd = jitdriver_sd return jitcell_token
def test_call_alignment_call_assembler(self): from pypy.rlib.libffi import types cpu = self.cpu if not cpu.supports_floats: py.test.skip('requires floats') fdescr3 = BasicFailDescr(3) fdescr4 = BasicFailDescr(4) def assembler_helper(failindex, virtualizable): assert 0, 'should not be called, but was with failindex (%d)' % failindex return 13 FUNCPTR = lltype.Ptr( lltype.FuncType([lltype.Signed, llmemory.GCREF], lltype.Signed)) class FakeJitDriverSD: index_of_virtualizable = -1 _assembler_helper_ptr = llhelper(FUNCPTR, assembler_helper) assembler_helper_adr = llmemory.cast_ptr_to_adr( _assembler_helper_ptr) floats = [0.7, 5.8, 0.1, 0.3, 0.9, -2.34, -3.45, -4.56] ints = [7, 11, 23, 42, -42, 1111, 95, 1] for case in range(256): float_count = 0 int_count = 0 args = [] called_ops = '' total_index = -1 for i in range(8): if case & (1 << i): args.append('f%d' % float_count) else: args.append('i%d' % int_count) called_ops += 'f%d = cast_int_to_float(i%d)\n' % ( float_count, int_count) int_count += 1 if total_index == -1: total_index = float_count float_count += 1 else: called_ops += 'f%d = float_add(f%d, f%d)\n' % ( float_count + 1, total_index, float_count) total_index = float_count + 1 float_count += 2 arguments = ', '.join(args) called_ops = '[%s]\n' % arguments + called_ops called_ops += 'finish(f%d, descr=fdescr3)\n' % total_index # compile called loop called_loop = parse(called_ops, namespace=locals()) called_looptoken = JitCellToken() called_looptoken.outermost_jitdriver_sd = FakeJitDriverSD() done_number = self.cpu.get_fail_descr_number( called_loop.operations[-1].getdescr()) self.cpu.compile_loop(called_loop.inputargs, called_loop.operations, called_looptoken) argvals, expected_result = self._prepare_args(args, floats, ints) res = cpu.execute_token(called_looptoken, *argvals) assert res.identifier == 3 t = longlong.getrealfloat(cpu.get_latest_value_float(0)) assert abs(t - expected_result) < 0.0001 ARGS = [] RES = lltype.Float for x in args: if x[0] == 'f': ARGS.append(lltype.Float) else: ARGS.append(lltype.Signed) FakeJitDriverSD.portal_calldescr = self.cpu.calldescrof( lltype.Ptr(lltype.FuncType(ARGS, RES)), ARGS, RES, EffectInfo.MOST_GENERAL) ops = ''' [%s] f99 = call_assembler(%s, descr=called_looptoken) guard_not_forced()[] finish(f99, descr=fdescr4) ''' % (arguments, arguments) loop = parse(ops, namespace=locals()) # we want to take the fast path self.cpu.done_with_this_frame_float_v = done_number try: othertoken = JitCellToken() self.cpu.compile_loop(loop.inputargs, loop.operations, othertoken) # prepare call to called_loop argvals, _ = self._prepare_args(args, floats, ints) res = cpu.execute_token(othertoken, *argvals) x = longlong.getrealfloat(cpu.get_latest_value_float(0)) assert res.identifier == 4 assert abs(x - expected_result) < 0.0001 finally: del self.cpu.done_with_this_frame_float_v
def test_call_alignment_call_assembler(self): from pypy.rlib.libffi import types cpu = self.cpu if not cpu.supports_floats: py.test.skip('requires floats') fdescr3 = BasicFailDescr(3) fdescr4 = BasicFailDescr(4) def assembler_helper(failindex, virtualizable): assert 0, 'should not be called, but was with failindex (%d)' % failindex return 13 FUNCPTR = lltype.Ptr(lltype.FuncType([lltype.Signed, llmemory.GCREF], lltype.Signed)) class FakeJitDriverSD: index_of_virtualizable = -1 _assembler_helper_ptr = llhelper(FUNCPTR, assembler_helper) assembler_helper_adr = llmemory.cast_ptr_to_adr( _assembler_helper_ptr) floats = [0.7, 5.8, 0.1, 0.3, 0.9, -2.34, -3.45, -4.56] ints = [7, 11, 23, 42, -42, 1111, 95, 1] for case in range(256): float_count = 0 int_count = 0 args = [] called_ops = '' total_index = -1 for i in range(8): if case & (1<<i): args.append('f%d' % float_count) else: args.append('i%d' % int_count) called_ops += 'f%d = cast_int_to_float(i%d)\n' % ( float_count, int_count) int_count += 1 if total_index == -1: total_index = float_count float_count += 1 else: called_ops += 'f%d = float_add(f%d, f%d)\n' % ( float_count + 1, total_index, float_count) total_index = float_count + 1 float_count += 2 arguments = ', '.join(args) called_ops = '[%s]\n' % arguments + called_ops called_ops += 'finish(f%d, descr=fdescr3)\n' % total_index # compile called loop called_loop = parse(called_ops, namespace=locals()) called_looptoken = JitCellToken() called_looptoken.outermost_jitdriver_sd = FakeJitDriverSD() done_number = self.cpu.get_fail_descr_number(called_loop.operations[-1].getdescr()) self.cpu.compile_loop(called_loop.inputargs, called_loop.operations, called_looptoken) argvals, expected_result = self._prepare_args(args, floats, ints) res = cpu.execute_token(called_looptoken, *argvals) assert res.identifier == 3 t = longlong.getrealfloat(cpu.get_latest_value_float(0)) assert abs(t - expected_result) < 0.0001 ARGS = [] RES = lltype.Float for x in args: if x[0] == 'f': ARGS.append(lltype.Float) else: ARGS.append(lltype.Signed) FakeJitDriverSD.portal_calldescr = self.cpu.calldescrof( lltype.Ptr(lltype.FuncType(ARGS, RES)), ARGS, RES, EffectInfo.MOST_GENERAL) ops = ''' [%s] f99 = call_assembler(%s, descr=called_looptoken) guard_not_forced()[] finish(f99, descr=fdescr4) ''' % (arguments, arguments) loop = parse(ops, namespace=locals()) # we want to take the fast path self.cpu.done_with_this_frame_float_v = done_number try: othertoken = JitCellToken() self.cpu.compile_loop(loop.inputargs, loop.operations, othertoken) # prepare call to called_loop argvals, _ = self._prepare_args(args, floats, ints) res = cpu.execute_token(othertoken, *argvals) x = longlong.getrealfloat(cpu.get_latest_value_float(0)) assert res.identifier == 4 assert abs(x - expected_result) < 0.0001 finally: del self.cpu.done_with_this_frame_float_v