Example #1
0
def test_elidable_kinds():
    from rpython.jit.backend.llgraph.runner import LLGraphCPU

    @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

    def f(n, m):
        a = f1(n, m)
        b = f2(n, m)
        c = f3(n, m)
        return a + len(b) + c

    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)]:
        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
Example #2
0
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()
Example #3
0
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), (1, True), (2, False), (3, False)]:  # f1()  # f2()  # len()  # 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
Example #4
0
def test_instantiate_with_unreasonable_attr():
    # It is possible to have in real code the instantiate() function for
    # a class be dont-look-inside.  This is caused by the code that
    # initialize the instance attributes: if one attribute has a strange
    # type, the whole function is disabled.  Check that it still works.
    class MyFakePolicy:
        def look_inside_graph(self, graph):
            name = graph.name
            return not (name.startswith('instantiate_') and
                        name.endswith('A2'))

    class A1:
        pass

    class A2(A1):
        pass

    classes = [A1, A2]

    def f(n):
        x = classes[n]
        x()
    rtyper = support.annotate(f, [1])
    maingraph = rtyper.annotator.translator.graphs[0]
    cw = CodeWriter(FakeCPU(rtyper), [FakeJitDriverSD(maingraph)])
    cw.find_all_graphs(MyFakePolicy())
    cw.make_jitcodes(verbose=True)
    #
    names = [jitcode.name for jitcode in cw.assembler.indirectcalltargets]
    assert len(names) == 1
    assert names[0].startswith('instantiate_') and names[0].endswith('A1')
Example #5
0
 def transform_func_to_jitcode(self, func, values):
     """For testing."""
     rtyper = support.annotate(func, values)
     graph = rtyper.annotator.translator.graphs[0]
     jitcode = JitCode("test")
     self.transform_graph_to_jitcode(graph, jitcode, True)
     return jitcode
Example #6
0
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)
Example #7
0
def test_find_all_graphs():
    def g(x):
        return x + 2
    def f(x):
        return g(x) + 1
    rtyper = support.annotate(f, [7])
    jitdriver_sd = FakeJitDriverSD(rtyper.annotator.translator.graphs[0])
    cc = CallControl(jitdrivers_sd=[jitdriver_sd])
    res = cc.find_all_graphs(FakePolicy())
    funcs = set([graph.func for graph in res])
    assert funcs == set([f, g])
Example #8
0
def test_int_abs():
    def f(n):
        return abs(n)
    rtyper = support.annotate(f, [35])
    jitdriver_sd = FakeJitDriverSD(rtyper.annotator.translator.graphs[0])
    cw = CodeWriter(FakeCPU(rtyper), [jitdriver_sd])
    cw.find_all_graphs(FakePolicy())
    cw.make_jitcodes(verbose=True)
    #
    s = jitdriver_sd.mainjitcode.dump()
    assert "inline_call_ir_i <JitCode '_ll_1_int_abs__Signed'>" in s
Example #9
0
def test_find_all_graphs():
    def g(x):
        return x + 2

    def f(x):
        return g(x) + 1

    rtyper = support.annotate(f, [7])
    jitdriver_sd = FakeJitDriverSD(rtyper.annotator.translator.graphs[0])
    cc = CallControl(jitdrivers_sd=[jitdriver_sd])
    res = cc.find_all_graphs(FakePolicy())
    funcs = set([graph.func for graph in res])
    assert funcs == set([f, g])
Example #10
0
def test_newlist_negativ():
    def f(n):
        l = [0] * n
        return len(l)

    rtyper = support.annotate(f, [-1])
    jitdriver_sd = FakeJitDriverSD(rtyper.annotator.translator.graphs[0])
    cw = CodeWriter(FakeCPU(rtyper), [jitdriver_sd])
    graphs = cw.find_all_graphs(FakePolicy())
    backend_optimizations(rtyper.annotator.translator, graphs=graphs)
    cw.make_jitcodes(verbose=True)
    s = jitdriver_sd.mainjitcode.dump()
    assert 'int_force_ge_zero' in s
    assert 'new_array' in s
Example #11
0
def test_find_all_graphs_without_g():
    def g(x):
        return x + 2
    def f(x):
        return g(x) + 1
    rtyper = support.annotate(f, [7])
    jitdriver_sd = FakeJitDriverSD(rtyper.annotator.translator.graphs[0])
    cc = CallControl(jitdrivers_sd=[jitdriver_sd])
    class CustomFakePolicy:
        def look_inside_graph(self, graph):
            assert graph.name == 'g'
            return False
    res = cc.find_all_graphs(CustomFakePolicy())
    funcs = [graph.func for graph in res]
    assert funcs == [f]
Example #12
0
def test_access_directly_but_not_seen():
    class X:
        _virtualizable_ = ["a"]
    def h(x, y):
        w = 0
        for i in range(y):
            w += 4
        return w
    def f(y):
        x = jit.hint(X(), access_directly=True)
        h(x, y)
    rtyper = support.annotate(f, [3])
    h_graph = rtyper.annotator.translator.graphs[1]
    assert h_graph.func is h
    py.test.raises(ValueError, JitPolicy().look_inside_graph, h_graph)
Example #13
0
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
Example #14
0
def test_access_directly_but_not_seen():
    class X:
        _virtualizable_ = ["a"]

    def h(x, y):
        w = 0
        for i in range(y):
            w += 4
        return w

    def f(y):
        x = jit.hint(X(), access_directly=True)
        h(x, y)

    rtyper = support.annotate(f, [3])
    h_graph = rtyper.annotator.translator.graphs[1]
    assert h_graph.func is h
    py.test.raises(ValueError, JitPolicy().look_inside_graph, h_graph)
Example #15
0
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)
Example #16
0
def test_find_all_graphs_without_g():
    def g(x):
        return x + 2

    def f(x):
        return g(x) + 1

    rtyper = support.annotate(f, [7])
    jitdriver_sd = FakeJitDriverSD(rtyper.annotator.translator.graphs[0])
    cc = CallControl(jitdrivers_sd=[jitdriver_sd])

    class CustomFakePolicy:
        def look_inside_graph(self, graph):
            assert graph.name == 'g'
            return False

    res = cc.find_all_graphs(CustomFakePolicy())
    funcs = [graph.func for graph in res]
    assert funcs == [f]
Example #17
0
def test_call():
    def ggg(x):
        return x * 2
    def fff(a, b):
        return ggg(b) - ggg(a)
    rtyper = support.annotate(fff, [35, 42])
    jitdriver_sd = FakeJitDriverSD(rtyper.annotator.translator.graphs[0])
    cw = CodeWriter(FakeCPU(rtyper), [jitdriver_sd])
    cw.find_all_graphs(FakePolicy())
    cw.make_jitcodes(verbose=True)
    jitcode = jitdriver_sd.mainjitcode
    print jitcode.dump()
    [jitcode2] = cw.assembler.descrs
    print jitcode2.dump()
    assert jitcode is not jitcode2
    assert jitcode.name == 'fff'
    assert jitcode2.name == 'ggg'
    assert 'ggg' in jitcode.dump()
    assert lltype.typeOf(jitcode2.fnaddr) == llmemory.Address
    assert isinstance(jitcode2.calldescr, FakeCallDescr)
Example #18
0
def test_call():
    def ggg(x):
        return x * 2
    def fff(a, b):
        return ggg(b) - ggg(a)
    rtyper = support.annotate(fff, [35, 42])
    jitdriver_sd = FakeJitDriverSD(rtyper.annotator.translator.graphs[0])
    cw = CodeWriter(FakeCPU(rtyper), [jitdriver_sd])
    cw.find_all_graphs(FakePolicy())
    cw.make_jitcodes(verbose=True)
    jitcode = jitdriver_sd.mainjitcode
    print jitcode.dump()
    [jitcode2] = cw.assembler.descrs
    print jitcode2.dump()
    assert jitcode is not jitcode2
    assert jitcode.name == 'fff'
    assert jitcode2.name == 'ggg'
    assert 'ggg' in jitcode.dump()
    assert lltype.typeOf(jitcode2.fnaddr) == llmemory.Address
    assert isinstance(jitcode2.calldescr, FakeCallDescr)
Example #19
0
def test_instantiate():
    class A1:
        id = 651

    class A2(A1):
        id = 652

    class B1:
        id = 661

    class B2(B1):
        id = 662

    def dont_look(n):
        return n + 1

    classes = [
        (A1, B1),
        (A2, B2)
    ]

    def f(n):
        x, y = classes[n]
        return x().id + y().id + dont_look(n)
    rtyper = support.annotate(f, [0])
    maingraph = rtyper.annotator.translator.graphs[0]
    cw = CodeWriter(FakeCPU(rtyper), [FakeJitDriverSD(maingraph)])
    cw.find_all_graphs(FakePolicy())
    cw.make_jitcodes(verbose=True)
    #
    assert len(cw.assembler.indirectcalltargets) == 4
    names = [jitcode.name for jitcode in cw.assembler.indirectcalltargets]
    for expected in ['A1', 'A2', 'B1', 'B2']:
        for name in names:
            if name.startswith('instantiate_') and name.endswith(expected):
                break
        else:
            assert 0, "missing instantiate_*_%s in:\n%r" % (expected,
                                                            names)
    names = set([value for key, value in cw.assembler.list_of_addr2name])
    assert 'dont_look' in names
Example #20
0
def test_instantiate():
    class A1:
        id = 651

    class A2(A1):
        id = 652

    class B1:
        id = 661

    class B2(B1):
        id = 662

    def dont_look(n):
        return n + 1

    classes = [
        (A1, B1),
        (A2, B2)
    ]

    def f(n):
        x, y = classes[n]
        return x().id + y().id + dont_look(n)
    rtyper = support.annotate(f, [0])
    maingraph = rtyper.annotator.translator.graphs[0]
    cw = CodeWriter(FakeCPU(rtyper), [FakeJitDriverSD(maingraph)])
    cw.find_all_graphs(FakePolicy())
    cw.make_jitcodes(verbose=True)
    #
    assert len(cw.assembler.indirectcalltargets) == 4
    names = [jitcode.name for jitcode in cw.assembler.indirectcalltargets]
    for expected in ['A1', 'A2', 'B1', 'B2']:
        for name in names:
            if name.startswith('instantiate_') and name.endswith(expected):
                break
        else:
            assert 0, "missing instantiate_*_%s in:\n%r" % (expected,
                                                            names)
    names = set([value for key, value in cw.assembler.list_of_addr2name])
    assert 'dont_look' in names
Example #21
0
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)
Example #22
0
def test_raw_malloc_and_access():
    TP = rffi.CArray(lltype.Signed)

    def f(n):
        a = lltype.malloc(TP, n, flavor='raw')
        a[0] = n
        res = a[0]
        lltype.free(a, flavor='raw')
        return res

    rtyper = support.annotate(f, [35])
    jitdriver_sd = FakeJitDriverSD(rtyper.annotator.translator.graphs[0])
    cw = CodeWriter(FakeCPU(rtyper), [jitdriver_sd])
    cw.find_all_graphs(FakePolicy())
    cw.make_jitcodes(verbose=True)
    #
    s = jitdriver_sd.mainjitcode.dump()
    assert 'residual_call_ir_i $<* fn _ll_1_raw_malloc_varsize__Signed>' in s
    assert 'setarrayitem_raw_i' in s
    assert 'getarrayitem_raw_i' in s
    assert 'residual_call_ir_v $<* fn _ll_1_raw_free__arrayPtr>' in s
Example #23
0
def test_raw_malloc_and_access():
    TP = rffi.CArray(lltype.Signed)

    def f(n):
        a = lltype.malloc(TP, n, flavor='raw')
        a[0] = n
        res = a[0]
        lltype.free(a, flavor='raw')
        return res

    rtyper = support.annotate(f, [35])
    jitdriver_sd = FakeJitDriverSD(rtyper.annotator.translator.graphs[0])
    cw = CodeWriter(FakeCPU(rtyper), [jitdriver_sd])
    cw.find_all_graphs(FakePolicy())
    cw.make_jitcodes(verbose=True)
    #
    s = jitdriver_sd.mainjitcode.dump()
    assert 'residual_call_ir_i $<* fn _ll_1_raw_malloc_varsize__Signed>' in s
    assert 'setarrayitem_raw_i' in s
    assert 'getarrayitem_raw_i' in s
    assert 'residual_call_ir_v $<* fn _ll_1_raw_free__arrayPtr>' in s
Example #24
0
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
Example #25
0
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
Example #26
0
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()
Example #27
0
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()
Example #28
0
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 setup_class(cls):
        from rpython.jit.metainterp.typesystem import llhelper
        from rpython.jit.codewriter.support import annotate
        from rpython.jit.metainterp.warmspot import WarmRunnerDesc
        from rpython.rtyper.rclass import OBJECT, OBJECT_VTABLE
        from rpython.rtyper.lltypesystem import lltype, llmemory
        exc_vtable = lltype.malloc(OBJECT_VTABLE, immortal=True)
        cls.exc_vtable = exc_vtable

        class FakeFailDescr(object):
            def __init__(self, no):
                self.no = no
            def handle_fail(self, deadframe, metainterp_sd, jitdrivers_sd):
                no = self.no
                assert deadframe._no == no
                if no == 0:
                    raise jitexc.DoneWithThisFrameInt(3)
                if no == 1:
                    raise jitexc.ContinueRunningNormally(
                        [0], [], [], [1], [], [])
                if no == 3:
                    exc = lltype.malloc(OBJECT)
                    exc.typeptr = exc_vtable
                    raise jitexc.ExitFrameWithExceptionRef(
                        metainterp_sd.cpu,
                        lltype.cast_opaque_ptr(llmemory.GCREF, exc))
                assert 0

        class FakeDeadFrame:
            def __init__(self, no):
                self._no = no

        class FakeDescr:
            pass

        class FakeCPU(object):
            supports_floats = False
            supports_longlong = False
            supports_singlefloats = False
            ts = llhelper
            translate_support_code = False
            stats = "stats"

            class tracker:
                pass

            def setup_descrs(self):
                return []

            def get_latest_descr(self, deadframe):
                assert isinstance(deadframe, FakeDeadFrame)
                return self.get_fail_descr_from_number(deadframe._no)

            def get_fail_descr_number(self, d):
                return -1

            def __init__(self, *args, **kwds):
                pass

            def nodescr(self, *args, **kwds):
                return FakeDescr()
            fielddescrof = nodescr
            calldescrof  = nodescr
            sizeof       = nodescr

            def get_fail_descr_from_number(self, no):
                return FakeFailDescr(no)

            def make_execute_token(self, *ARGS):
                return "not callable"

        driver = JitDriver(reds = ['red'], greens = ['green'])

        def f(green):
            red = 0
            while red < 10:
                driver.can_enter_jit(red=red, green=green)
                driver.jit_merge_point(red=red, green=green)
                red += 1
            return red

        rtyper = annotate(f, [0])
        FakeCPU.rtyper = rtyper
        translator = rtyper.annotator.translator
        translator.config.translation.gc = 'hybrid'
        cls.desc = WarmRunnerDesc(translator, CPUClass=FakeCPU)
        cls.FakeDeadFrame = FakeDeadFrame
Example #30
0
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]
Example #31
0
 def make_graphs(self, func, values, type_system='lltype'):
     self.rtyper = support.annotate(func, values, type_system=type_system)
     return self.rtyper.annotator.translator.graphs
Example #32
0
def _get_jitcodes(testself, CPUClass, func, values,
                  supports_floats=True,
                  supports_longlong=False,
                  supports_singlefloats=False,
                  translationoptions={}, **kwds):
    from rpython.jit.codewriter import support

    class FakeJitCell(object):
        __product_token = None
        def get_procedure_token(self):
            return self.__product_token
        def set_procedure_token(self, token):
            self.__product_token = token

    class FakeWarmRunnerState(object):
        def attach_procedure_to_interp(self, greenkey, procedure_token):
            assert greenkey == []
            self._cell.set_procedure_token(procedure_token)

        def helper_func(self, FUNCPTR, func):
            from rpython.rtyper.annlowlevel import llhelper
            return llhelper(FUNCPTR, func)

        def get_unique_id(self, *args):
            return 0

        def get_location_str(self, args):
            return 'location'

        class JitCell:
            @staticmethod
            def get_jit_cell_at_key(greenkey):
                assert greenkey == []
                return FakeWarmRunnerState._cell
        _cell = FakeJitCell()

        trace_limit = sys.maxint
        enable_opts = ALL_OPTS_DICT
        vec = True

    if kwds.pop('disable_optimizations', False):
        FakeWarmRunnerState.enable_opts = {}

    func._jit_unroll_safe_ = True
    rtyper = support.annotate(func, values,
                              translationoptions=translationoptions)
    graphs = rtyper.annotator.translator.graphs
    testself.all_graphs = graphs
    result_kind = history.getkind(graphs[0].getreturnvar().concretetype)[0]


    class FakeJitDriver:
        name = 'fakejitdriver'

    class FakeJitDriverSD:
        num_green_args = 0
        portal_graph = graphs[0]
        virtualizable_info = None
        greenfield_info = None
        result_type = result_kind
        portal_runner_ptr = "???"
        vec = False
        jitdriver = FakeJitDriver()

    stats = history.Stats(None)
    cpu = CPUClass(rtyper, stats, None, False)
    cw = codewriter.CodeWriter(cpu, [FakeJitDriverSD()])
    cw.debug = True
    testself.cw = cw
    if supports_floats and not cpu.supports_floats:
        py.test.skip("this test requires supports_floats=True")
    if supports_longlong and not cpu.supports_longlong:
        py.test.skip("this test requires supports_longlong=True")
    if supports_singlefloats and not cpu.supports_singlefloats:
        py.test.skip("this test requires supports_singlefloats=True")
    policy = JitPolicy()
    policy.set_supports_floats(supports_floats)
    policy.set_supports_longlong(supports_longlong)
    policy.set_supports_singlefloats(supports_singlefloats)
    graphs = cw.find_all_graphs(policy)
    if kwds.get("backendopt"):
        backend_optimizations(rtyper.annotator.translator, graphs=graphs)
    #
    testself.warmrunnerstate = FakeWarmRunnerState()
    testself.warmrunnerstate.cpu = cpu
    FakeJitDriverSD.warmstate = testself.warmrunnerstate
    if hasattr(testself, 'finish_setup_for_interp_operations'):
        testself.finish_setup_for_interp_operations()
    #
    cw.make_jitcodes(verbose=True)
    return stats
Example #33
0
def _get_jitcodes(testself,
                  CPUClass,
                  func,
                  values,
                  supports_floats=True,
                  supports_longlong=False,
                  supports_singlefloats=False,
                  translationoptions={},
                  **kwds):
    from rpython.jit.codewriter import support

    class FakeJitCell(object):
        __product_token = None

        def get_procedure_token(self):
            return self.__product_token

        def set_procedure_token(self, token):
            self.__product_token = token

    class FakeWarmRunnerState(object):
        def attach_procedure_to_interp(self, greenkey, procedure_token):
            assert greenkey == []
            self._cell.set_procedure_token(procedure_token)

        def helper_func(self, FUNCPTR, func):
            from rpython.rtyper.annlowlevel import llhelper
            return llhelper(FUNCPTR, func)

        def get_unique_id(self, *args):
            return 0

        def get_location_str(self, args):
            return 'location'

        class JitCell:
            @staticmethod
            def get_jit_cell_at_key(greenkey):
                assert greenkey == []
                return FakeWarmRunnerState._cell

        _cell = FakeJitCell()

        trace_limit = sys.maxint
        enable_opts = ALL_OPTS_DICT
        vec = True

    if kwds.pop('disable_optimizations', False):
        FakeWarmRunnerState.enable_opts = {}

    func._jit_unroll_safe_ = True
    rtyper = support.annotate(func,
                              values,
                              translationoptions=translationoptions)
    graphs = rtyper.annotator.translator.graphs
    testself.all_graphs = graphs
    result_kind = history.getkind(graphs[0].getreturnvar().concretetype)[0]

    class FakeJitDriverSD:
        num_green_args = 0
        portal_graph = graphs[0]
        virtualizable_info = None
        greenfield_info = None
        result_type = result_kind
        portal_runner_ptr = "???"
        vec = False

    stats = history.Stats(None)
    cpu = CPUClass(rtyper, stats, None, False)
    cw = codewriter.CodeWriter(cpu, [FakeJitDriverSD()])
    cw.debug = True
    testself.cw = cw
    if supports_floats and not cpu.supports_floats:
        py.test.skip("this test requires supports_floats=True")
    if supports_longlong and not cpu.supports_longlong:
        py.test.skip("this test requires supports_longlong=True")
    if supports_singlefloats and not cpu.supports_singlefloats:
        py.test.skip("this test requires supports_singlefloats=True")
    policy = JitPolicy()
    policy.set_supports_floats(supports_floats)
    policy.set_supports_longlong(supports_longlong)
    policy.set_supports_singlefloats(supports_singlefloats)
    graphs = cw.find_all_graphs(policy)
    if kwds.get("backendopt"):
        backend_optimizations(rtyper.annotator.translator, graphs=graphs)
    #
    testself.warmrunnerstate = FakeWarmRunnerState()
    testself.warmrunnerstate.cpu = cpu
    FakeJitDriverSD.warmstate = testself.warmrunnerstate
    if hasattr(testself, 'finish_setup_for_interp_operations'):
        testself.finish_setup_for_interp_operations()
    #
    cw.make_jitcodes(verbose=True)
    return stats
Example #34
0
    def setup_class(cls):
        from rpython.jit.metainterp.typesystem import llhelper
        from rpython.jit.codewriter.support import annotate
        from rpython.jit.metainterp.warmspot import WarmRunnerDesc
        from rpython.rtyper.rclass import OBJECT, OBJECT_VTABLE
        from rpython.rtyper.lltypesystem import lltype, llmemory
        exc_vtable = lltype.malloc(OBJECT_VTABLE, immortal=True)
        cls.exc_vtable = exc_vtable

        class FakeFailDescr(object):
            def __init__(self, no):
                self.no = no
            def handle_fail(self, deadframe, metainterp_sd, jitdrivers_sd):
                no = self.no
                assert deadframe._no == no
                if no == 0:
                    raise jitexc.DoneWithThisFrameInt(3)
                if no == 1:
                    raise jitexc.ContinueRunningNormally(
                        [0], [], [], [1], [], [])
                if no == 3:
                    exc = lltype.malloc(OBJECT)
                    exc.typeptr = exc_vtable
                    raise jitexc.ExitFrameWithExceptionRef(
                        metainterp_sd.cpu,
                        lltype.cast_opaque_ptr(llmemory.GCREF, exc))
                assert 0

        class FakeDeadFrame:
            def __init__(self, no):
                self._no = no

        class FakeDescr:
            pass

        class FakeCPU(object):
            supports_floats = False
            supports_longlong = False
            supports_singlefloats = False
            ts = llhelper
            translate_support_code = False
            stats = "stats"

            class tracker:
                pass

            def get_latest_descr(self, deadframe):
                assert isinstance(deadframe, FakeDeadFrame)
                return self.get_fail_descr_from_number(deadframe._no)

            def get_fail_descr_number(self, d):
                return -1

            def __init__(self, *args, **kwds):
                pass

            def nodescr(self, *args, **kwds):
                return FakeDescr()
            fielddescrof = nodescr
            calldescrof  = nodescr
            sizeof       = nodescr

            def get_fail_descr_from_number(self, no):
                return FakeFailDescr(no)

            def make_execute_token(self, *ARGS):
                return "not callable"

        driver = JitDriver(reds = ['red'], greens = ['green'])

        def f(green):
            red = 0
            while red < 10:
                driver.can_enter_jit(red=red, green=green)
                driver.jit_merge_point(red=red, green=green)
                red += 1
            return red

        rtyper = annotate(f, [0])
        FakeCPU.rtyper = rtyper
        translator = rtyper.annotator.translator
        translator.config.translation.gc = 'hybrid'
        cls.desc = WarmRunnerDesc(translator, CPUClass=FakeCPU)
        cls.FakeDeadFrame = FakeDeadFrame
Example #35
0
 def make_graphs(self, func, values):
     self.rtyper = support.annotate(func, values)
     return self.rtyper.annotator.translator.graphs