def test_random_effects_on_stacklet_switch(): from rpython.jit.backend.llgraph.runner import LLGraphCPU from rpython.translator.platform import CompilationError try: from rpython.rlib._rffi_stacklet import switch, handle except CompilationError as e: if "Unsupported platform!" in e.out: py.test.skip("Unsupported platform!") else: raise e @jit.dont_look_inside def f(): switch(rffi.cast(handle, 0)) rtyper = support.annotate(f, []) jitdriver_sd = FakeJitDriverSD(rtyper.annotator.translator.graphs[0]) cc = CallControl(LLGraphCPU(rtyper), jitdrivers_sd=[jitdriver_sd]) res = cc.find_all_graphs(FakePolicy()) [f_graph] = [x for x in res if x.func is f] [block, _] = list(f_graph.iterblocks()) op = block.operations[-1] call_descr = cc.getcalldescr(op) assert call_descr.extrainfo.has_random_effects()
def test_call_release_gil(): from rpython.jit.backend.llgraph.runner import LLGraphCPU T = rffi.CArrayPtr(rffi.TIME_T) external = rffi.llexternal("time", [T], rffi.TIME_T, releasegil=True, save_err=rffi.RFFI_SAVE_ERRNO) # no jit.dont_look_inside in this test def f(): return external(lltype.nullptr(T.TO)) rtyper = support.annotate(f, []) jitdriver_sd = FakeJitDriverSD(rtyper.annotator.translator.graphs[0]) cc = CallControl(LLGraphCPU(rtyper), jitdrivers_sd=[jitdriver_sd]) res = cc.find_all_graphs(FakePolicy()) [llext_graph] = [x for x in res if x.func is external] [block, _] = list(llext_graph.iterblocks()) [op] = block.operations tgt_tuple = op.args[0].value._obj.graph.func._call_aroundstate_target_ assert type(tgt_tuple) is tuple and len(tgt_tuple) == 2 call_target, saveerr = tgt_tuple assert saveerr == rffi.RFFI_SAVE_ERRNO call_target = llmemory.cast_ptr_to_adr(call_target) call_descr = cc.getcalldescr(op) assert call_descr.extrainfo.has_random_effects() assert call_descr.extrainfo.is_call_release_gil() is True assert call_descr.extrainfo.call_release_gil_target == ( call_target, rffi.RFFI_SAVE_ERRNO)
def get_cpu(): if pytest.config.option.backend == 'llgraph': from rpython.jit.backend.llgraph.runner import LLGraphCPU return LLGraphCPU(None) elif pytest.config.option.backend == 'cpu': from rpython.jit.backend.detect_cpu import getcpuclass return getcpuclass()(None, None) else: assert 0, "unknown backend %r" % pytest.config.option.backend
def test_elidable_kinds(): from rpython.jit.backend.llgraph.runner import LLGraphCPU from rpython.rlib.objectmodel import compute_hash from rpython.rlib.rsiphash import enable_siphash24 @jit.elidable def f1(n, m): return n + m @jit.elidable def f2(n, m): return [n, m] # may raise MemoryError @jit.elidable def f3(n, m): if n > m: raise ValueError return n + m @jit.elidable def f4(n, m): return compute_hash(str(n) + str(m)) def f(n, m): a = f1(n, m) b = f2(n, m) c = f3(n, m) d = f4(n, m) enable_siphash24() return a + len(b) + c + d rtyper = support.annotate(f, [7, 9]) jitdriver_sd = FakeJitDriverSD(rtyper.annotator.translator.graphs[0]) cc = CallControl(LLGraphCPU(rtyper), jitdrivers_sd=[jitdriver_sd]) res = cc.find_all_graphs(FakePolicy()) [f_graph] = [x for x in res if x.func is f] for index, expected in [(0, EffectInfo.EF_ELIDABLE_CANNOT_RAISE), (1, EffectInfo.EF_ELIDABLE_OR_MEMORYERROR), (2, EffectInfo.EF_ELIDABLE_CAN_RAISE), (3, EffectInfo.EF_ELIDABLE_OR_MEMORYERROR)]: call_op = f_graph.startblock.operations[index] assert call_op.opname == 'direct_call' call_descr = cc.getcalldescr(call_op) assert call_descr.extrainfo.extraeffect == expected
def test_releases_gil_analyzer(): from rpython.jit.backend.llgraph.runner import LLGraphCPU T = rffi.CArrayPtr(rffi.TIME_T) external = rffi.llexternal("time", [T], rffi.TIME_T, releasegil=True) @jit.dont_look_inside def f(): return external(lltype.nullptr(T.TO)) rtyper = support.annotate(f, []) jitdriver_sd = FakeJitDriverSD(rtyper.annotator.translator.graphs[0]) cc = CallControl(LLGraphCPU(rtyper), jitdrivers_sd=[jitdriver_sd]) res = cc.find_all_graphs(FakePolicy()) [f_graph] = [x for x in res if x.func is f] [block, _] = list(f_graph.iterblocks()) [op] = block.operations call_descr = cc.getcalldescr(op) assert call_descr.extrainfo.has_random_effects() assert call_descr.extrainfo.is_call_release_gil() is False
def test_raise_elidable_no_result(): from rpython.jit.backend.llgraph.runner import LLGraphCPU l = [] @jit.elidable def f1(n, m): l.append(n) def f(n, m): f1(n, m) return n + m rtyper = support.annotate(f, [7, 9]) jitdriver_sd = FakeJitDriverSD(rtyper.annotator.translator.graphs[0]) cc = CallControl(LLGraphCPU(rtyper), jitdrivers_sd=[jitdriver_sd]) res = cc.find_all_graphs(FakePolicy()) [f_graph] = [x for x in res if x.func is f] call_op = f_graph.startblock.operations[0] assert call_op.opname == 'direct_call' with py.test.raises(Exception): call_descr = cc.getcalldescr(call_op)
def test_no_random_effects_for_rotateLeft(): from rpython.jit.backend.llgraph.runner import LLGraphCPU from rpython.rlib.rarithmetic import r_uint if r_uint.BITS == 32: py.test.skip("64-bit only") from rpython.rlib.rmd5 import _rotateLeft def f(n, m): return _rotateLeft(r_uint(n), m) rtyper = support.annotate(f, [7, 9]) jitdriver_sd = FakeJitDriverSD(rtyper.annotator.translator.graphs[0]) cc = CallControl(LLGraphCPU(rtyper), jitdrivers_sd=[jitdriver_sd]) res = cc.find_all_graphs(FakePolicy()) [f_graph] = [x for x in res if x.func is f] [block, _] = list(f_graph.iterblocks()) op = block.operations[-1] call_descr = cc.getcalldescr(op) assert not call_descr.extrainfo.has_random_effects() assert call_descr.extrainfo.check_is_elidable()
def test_can_or_cannot_collect(): from rpython.jit.backend.llgraph.runner import LLGraphCPU prebuilts = [[5], [6]] l = [] def f1(n): if n > 1: raise IndexError return prebuilts[n] # cannot collect f1._dont_inline_ = True def f2(n): return [n] # can collect f2._dont_inline_ = True def f(n): a = f1(n) b = f2(n) return len(a) + len(b) rtyper = support.annotate(f, [1]) jitdriver_sd = FakeJitDriverSD(rtyper.annotator.translator.graphs[0]) cc = CallControl(LLGraphCPU(rtyper), jitdrivers_sd=[jitdriver_sd]) res = cc.find_all_graphs(FakePolicy()) [f_graph] = [x for x in res if x.func is f] for index, expected in [ (0, False), # f1() (1, True), # f2() (2, False), # len() (3, False) ]: # len() call_op = f_graph.startblock.operations[index] assert call_op.opname == 'direct_call' call_descr = cc.getcalldescr(call_op) assert call_descr.extrainfo.check_can_collect() == expected
def get_cpu(self): return LLGraphCPU(None)
def test_elidable_kinds(): from rpython.jit.backend.llgraph.runner import LLGraphCPU from rpython.rlib.objectmodel import compute_hash from rpython.rlib.rsiphash import enable_siphash24 @jit.elidable def f1(n, m): return n + m @jit.elidable def f2(n, m): return [n, m] # may raise MemoryError @jit.elidable def f3(n, m): if n > m: raise ValueError return n + m @jit.elidable def f4(n, m): return compute_hash(str(n) + str(m)) T = rffi.CArrayPtr(rffi.TIME_T) external = rffi.llexternal("time", [T], rffi.TIME_T, releasegil=True) def effect(): return external(lltype.nullptr(T.TO)) @jit.elidable def f5(n, m): effect() return 1 def f(n, m): a = f1(n, m) b = f2(n, m) c = f3(n, m) d = f4(n, m) f5(n, m) enable_siphash24() return a + len(b) + c + d rtyper = support.annotate(f, [7, 9]) jitdriver_sd = FakeJitDriverSD(rtyper.annotator.translator.graphs[0]) cc = CallControl(LLGraphCPU(rtyper), jitdrivers_sd=[jitdriver_sd]) res = cc.find_all_graphs(FakePolicy()) [f_graph] = [x for x in res if x.func is f] for index, expected in [(0, EffectInfo.EF_ELIDABLE_CANNOT_RAISE), (1, EffectInfo.EF_ELIDABLE_OR_MEMORYERROR), (2, EffectInfo.EF_ELIDABLE_CAN_RAISE), (3, EffectInfo.EF_ELIDABLE_OR_MEMORYERROR)]: call_op = f_graph.startblock.operations[index] assert call_op.opname == 'direct_call' call_descr = cc.getcalldescr(call_op) assert call_descr.extrainfo.extraeffect == expected call_op = f_graph.startblock.operations[4] assert call_op.opname == 'direct_call' excinfo = py.test.raises(Exception, cc.getcalldescr, call_op) lines = excinfo.value.args[0].splitlines() assert "f5" in lines[2] assert "effect" in lines[3] assert "random effects" in lines[-1]