/rpython/jit/metainterp/optimizeopt/test/test_util.py
Python | 673 lines | 667 code | 6 blank | 0 comment | 3 complexity | c1518f29bc459a3a83b3fcf7de55711a MD5 | raw file
Possible License(s): AGPL-3.0, BSD-3-Clause, Apache-2.0
- import py, random, string
- from rpython.rlib.debug import debug_print
- from rpython.rtyper.lltypesystem import lltype, llmemory, rffi
- from rpython.rtyper import rclass
- from rpython.rtyper.rclass import (
- OBJECT, OBJECT_VTABLE, FieldListAccessor, IR_QUASIIMMUTABLE)
- from rpython.jit.backend.llgraph import runner
- from rpython.jit.metainterp.history import (TreeLoop, AbstractDescr,
- JitCellToken, TargetToken)
- from rpython.jit.metainterp.optimizeopt.util import sort_descrs, equaloplists
- from rpython.jit.codewriter.effectinfo import EffectInfo, compute_bitstrings
- from rpython.jit.metainterp.logger import LogOperations
- from rpython.jit.tool.oparser import OpParser, pure_parse, convert_loop_to_trace
- from rpython.jit.metainterp.quasiimmut import QuasiImmutDescr
- from rpython.jit.metainterp import compile, resume, history
- from rpython.jit.metainterp.jitprof import EmptyProfiler
- from rpython.jit.metainterp.counter import DeterministicJitCounter
- from rpython.config.translationoption import get_combined_translation_config
- from rpython.jit.metainterp.resoperation import (rop, ResOperation,
- InputArgRef, AbstractValue, OpHelpers)
- from rpython.jit.metainterp.optimizeopt.util import args_dict
- from rpython.rlib.rjitlog import rjitlog as jl
- def test_sort_descrs():
- class PseudoDescr(AbstractDescr):
- def __init__(self, n):
- self.n = n
- def sort_key(self):
- return self.n
- for i in range(17):
- lst = [PseudoDescr(j) for j in range(i)]
- lst2 = lst[:]
- random.shuffle(lst2)
- sort_descrs(lst2)
- assert lst2 == lst
- def make_remap(inp1, inp2):
- remap = {}
- for a, b in zip(inp1, inp2):
- remap[b] = a
- return remap
- def test_equaloplists():
- ops = """
- [i0]
- i1 = int_add(i0, 1)
- i2 = int_add(i1, 1)
- guard_true(i1) [i2]
- jump(i1)
- """
- namespace = {}
- loop1 = pure_parse(ops, namespace=namespace)
- loop2 = pure_parse(ops, namespace=namespace)
- loop3 = pure_parse(ops.replace("i2 = int_add", "i2 = int_sub"),
- namespace=namespace)
- assert equaloplists(loop1.operations, loop2.operations,
- remap=make_remap(loop1.inputargs,
- loop2.inputargs))
- py.test.raises(AssertionError,
- "equaloplists(loop1.operations, loop3.operations,"
- "remap=make_remap(loop1.inputargs, loop3.inputargs))")
- def test_equaloplists_fail_args():
- ops = """
- [i0]
- i1 = int_add(i0, 1)
- i2 = int_add(i1, 1)
- guard_true(i1) [i2, i1]
- jump(i1)
- """
- namespace = {}
- loop1 = pure_parse(ops, namespace=namespace)
- loop2 = pure_parse(ops.replace("[i2, i1]", "[i1, i2]"),
- namespace=namespace)
- py.test.raises(AssertionError,
- "equaloplists(loop1.operations, loop2.operations,"
- "remap=make_remap(loop1.inputargs, loop2.inputargs))")
- assert equaloplists(loop1.operations, loop2.operations,
- remap=make_remap(loop1.inputargs, loop2.inputargs),
- strict_fail_args=False)
- loop3 = pure_parse(ops.replace("[i2, i1]", "[i2, i0]"),
- namespace=namespace)
- py.test.raises(AssertionError,
- "equaloplists(loop1.operations, loop3.operations,"
- " remap=make_remap(loop1.inputargs, loop3.inputargs))")
- # ____________________________________________________________
- class LLtypeMixin(object):
- def get_class_of_box(self, box):
- base = box.getref_base()
- return lltype.cast_opaque_ptr(rclass.OBJECTPTR, base).typeptr
- node_vtable = lltype.malloc(OBJECT_VTABLE, immortal=True)
- node_vtable.name = rclass.alloc_array_name('node')
- node_vtable_adr = llmemory.cast_ptr_to_adr(node_vtable)
- node_vtable2 = lltype.malloc(OBJECT_VTABLE, immortal=True)
- node_vtable2.name = rclass.alloc_array_name('node2')
- node_vtable_adr2 = llmemory.cast_ptr_to_adr(node_vtable2)
- node_vtable3 = lltype.malloc(OBJECT_VTABLE, immortal=True)
- node_vtable3.name = rclass.alloc_array_name('node3')
- node_vtable_adr3 = llmemory.cast_ptr_to_adr(node_vtable3)
- cpu = runner.LLGraphCPU(None)
- NODE = lltype.GcForwardReference()
- S = lltype.GcForwardReference()
- NODE.become(lltype.GcStruct('NODE', ('parent', OBJECT),
- ('value', lltype.Signed),
- ('floatval', lltype.Float),
- ('charval', lltype.Char),
- ('nexttuple', lltype.Ptr(S)),
- ('next', lltype.Ptr(NODE))))
- S.become(lltype.GcStruct('TUPLE', ('a', lltype.Signed), ('abis', lltype.Signed),
- ('b', lltype.Ptr(NODE))))
- NODE2 = lltype.GcStruct('NODE2', ('parent', NODE),
- ('other', lltype.Ptr(NODE)))
- NODE3 = lltype.GcForwardReference()
- NODE3.become(lltype.GcStruct('NODE3', ('parent', OBJECT),
- ('value', lltype.Signed),
- ('next', lltype.Ptr(NODE3)),
- hints={'immutable': True}))
- big_fields = [('big' + i, lltype.Signed) for i in string.ascii_lowercase]
- BIG = lltype.GcForwardReference()
- BIG.become(lltype.GcStruct('BIG', *big_fields, hints={'immutable': True}))
- for field, _ in big_fields:
- locals()[field + 'descr'] = cpu.fielddescrof(BIG, field)
- node = lltype.malloc(NODE)
- node.value = 5
- node.next = node
- node.parent.typeptr = node_vtable
- nodeaddr = lltype.cast_opaque_ptr(llmemory.GCREF, node)
- #nodebox = InputArgRef(lltype.cast_opaque_ptr(llmemory.GCREF, node))
- node2 = lltype.malloc(NODE2)
- node2.parent.parent.typeptr = node_vtable2
- node2addr = lltype.cast_opaque_ptr(llmemory.GCREF, node2)
- myptr = lltype.cast_opaque_ptr(llmemory.GCREF, node)
- mynodeb = lltype.malloc(NODE)
- myarray = lltype.cast_opaque_ptr(llmemory.GCREF, lltype.malloc(lltype.GcArray(lltype.Signed), 13, zero=True))
- mynodeb.parent.typeptr = node_vtable
- myptrb = lltype.cast_opaque_ptr(llmemory.GCREF, mynodeb)
- myptr2 = lltype.malloc(NODE2)
- myptr2.parent.parent.typeptr = node_vtable2
- myptr2 = lltype.cast_opaque_ptr(llmemory.GCREF, myptr2)
- nullptr = lltype.nullptr(llmemory.GCREF.TO)
- mynode3 = lltype.malloc(NODE3)
- mynode3.parent.typeptr = node_vtable3
- mynode3.value = 7
- mynode3.next = mynode3
- myptr3 = lltype.cast_opaque_ptr(llmemory.GCREF, mynode3) # a NODE2
- mynode4 = lltype.malloc(NODE3)
- mynode4.parent.typeptr = node_vtable3
- myptr4 = lltype.cast_opaque_ptr(llmemory.GCREF, mynode4) # a NODE3
- nullptr = lltype.nullptr(llmemory.GCREF.TO)
- #nodebox2 = InputArgRef(lltype.cast_opaque_ptr(llmemory.GCREF, node2))
- nodesize = cpu.sizeof(NODE, node_vtable)
- node_tid = nodesize.get_type_id()
- nodesize2 = cpu.sizeof(NODE2, node_vtable2)
- nodesize3 = cpu.sizeof(NODE3, node_vtable3)
- valuedescr = cpu.fielddescrof(NODE, 'value')
- floatdescr = cpu.fielddescrof(NODE, 'floatval')
- chardescr = cpu.fielddescrof(NODE, 'charval')
- nextdescr = cpu.fielddescrof(NODE, 'next')
- nexttupledescr = cpu.fielddescrof(NODE, 'nexttuple')
- otherdescr = cpu.fielddescrof(NODE2, 'other')
- valuedescr3 = cpu.fielddescrof(NODE3, 'value')
- nextdescr3 = cpu.fielddescrof(NODE3, 'next')
- assert valuedescr3.is_always_pure()
- assert nextdescr3.is_always_pure()
- accessor = FieldListAccessor()
- accessor.initialize(None, {'inst_field': IR_QUASIIMMUTABLE})
- QUASI = lltype.GcStruct('QUASIIMMUT', ('inst_field', lltype.Signed),
- ('mutate_field', rclass.OBJECTPTR),
- hints={'immutable_fields': accessor})
- quasisize = cpu.sizeof(QUASI, None)
- quasi = lltype.malloc(QUASI, immortal=True)
- quasi.inst_field = -4247
- quasifielddescr = cpu.fielddescrof(QUASI, 'inst_field')
- quasiptr = lltype.cast_opaque_ptr(llmemory.GCREF, quasi)
- quasiimmutdescr = QuasiImmutDescr(cpu, quasiptr, quasifielddescr,
- cpu.fielddescrof(QUASI, 'mutate_field'))
- NODEOBJ = lltype.GcStruct('NODEOBJ', ('parent', OBJECT),
- ('ref', lltype.Ptr(OBJECT)))
- nodeobj = lltype.malloc(NODEOBJ)
- nodeobjvalue = lltype.cast_opaque_ptr(llmemory.GCREF, nodeobj)
- refdescr = cpu.fielddescrof(NODEOBJ, 'ref')
- INTOBJ_NOIMMUT = lltype.GcStruct('INTOBJ_NOIMMUT', ('parent', OBJECT),
- ('intval', lltype.Signed))
- INTOBJ_IMMUT = lltype.GcStruct('INTOBJ_IMMUT', ('parent', OBJECT),
- ('intval', lltype.Signed),
- hints={'immutable': True})
- intobj_noimmut_vtable = lltype.malloc(OBJECT_VTABLE, immortal=True)
- intobj_immut_vtable = lltype.malloc(OBJECT_VTABLE, immortal=True)
- noimmut_intval = cpu.fielddescrof(INTOBJ_NOIMMUT, 'intval')
- immut_intval = cpu.fielddescrof(INTOBJ_IMMUT, 'intval')
- immut = lltype.malloc(INTOBJ_IMMUT, zero=True)
- immutaddr = lltype.cast_opaque_ptr(llmemory.GCREF, immut)
- noimmut_descr = cpu.sizeof(INTOBJ_NOIMMUT, intobj_noimmut_vtable)
- immut_descr = cpu.sizeof(INTOBJ_IMMUT, intobj_immut_vtable)
- PTROBJ_IMMUT = lltype.GcStruct('PTROBJ_IMMUT', ('parent', OBJECT),
- ('ptrval', lltype.Ptr(OBJECT)),
- hints={'immutable': True})
- ptrobj_immut_vtable = lltype.malloc(OBJECT_VTABLE, immortal=True)
- ptrobj_immut_descr = cpu.sizeof(PTROBJ_IMMUT, ptrobj_immut_vtable)
- immut_ptrval = cpu.fielddescrof(PTROBJ_IMMUT, 'ptrval')
- arraydescr = cpu.arraydescrof(lltype.GcArray(lltype.Signed))
- int32arraydescr = cpu.arraydescrof(lltype.GcArray(rffi.INT))
- int16arraydescr = cpu.arraydescrof(lltype.GcArray(rffi.SHORT))
- float32arraydescr = cpu.arraydescrof(lltype.GcArray(lltype.SingleFloat))
- arraydescr_tid = arraydescr.get_type_id()
- array = lltype.malloc(lltype.GcArray(lltype.Signed), 15, zero=True)
- arrayref = lltype.cast_opaque_ptr(llmemory.GCREF, array)
- array2 = lltype.malloc(lltype.GcArray(lltype.Ptr(S)), 15, zero=True)
- array2ref = lltype.cast_opaque_ptr(llmemory.GCREF, array2)
- gcarraydescr = cpu.arraydescrof(lltype.GcArray(llmemory.GCREF))
- gcarraydescr_tid = gcarraydescr.get_type_id()
- floatarraydescr = cpu.arraydescrof(lltype.GcArray(lltype.Float))
- arrayimmutdescr = cpu.arraydescrof(lltype.GcArray(lltype.Signed, hints={"immutable": True}))
- immutarray = lltype.cast_opaque_ptr(llmemory.GCREF, lltype.malloc(arrayimmutdescr.A, 13, zero=True))
- gcarrayimmutdescr = cpu.arraydescrof(lltype.GcArray(llmemory.GCREF, hints={"immutable": True}))
- floatarrayimmutdescr = cpu.arraydescrof(lltype.GcArray(lltype.Float, hints={"immutable": True}))
- # a GcStruct not inheriting from OBJECT
- tpl = lltype.malloc(S, zero=True)
- tupleaddr = lltype.cast_opaque_ptr(llmemory.GCREF, tpl)
- nodefull2 = lltype.malloc(NODE, zero=True)
- nodefull2addr = lltype.cast_opaque_ptr(llmemory.GCREF, nodefull2)
- ssize = cpu.sizeof(S, None)
- adescr = cpu.fielddescrof(S, 'a')
- abisdescr = cpu.fielddescrof(S, 'abis')
- bdescr = cpu.fielddescrof(S, 'b')
- #sbox = BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, lltype.malloc(S)))
- arraydescr2 = cpu.arraydescrof(lltype.GcArray(lltype.Ptr(S)))
- T = lltype.GcStruct('TUPLE',
- ('c', lltype.Signed),
- ('d', lltype.Ptr(lltype.GcArray(lltype.Ptr(NODE)))))
- W_ROOT = lltype.GcStruct('W_ROOT', ('parent', OBJECT),
- ('inst_w_seq', llmemory.GCREF), ('inst_index', lltype.Signed),
- ('inst_w_list', llmemory.GCREF), ('inst_length', lltype.Signed),
- ('inst_start', lltype.Signed), ('inst_step', lltype.Signed))
- inst_w_seq = cpu.fielddescrof(W_ROOT, 'inst_w_seq')
- inst_index = cpu.fielddescrof(W_ROOT, 'inst_index')
- inst_length = cpu.fielddescrof(W_ROOT, 'inst_length')
- inst_start = cpu.fielddescrof(W_ROOT, 'inst_start')
- inst_step = cpu.fielddescrof(W_ROOT, 'inst_step')
- inst_w_list = cpu.fielddescrof(W_ROOT, 'inst_w_list')
- w_root_vtable = lltype.malloc(OBJECT_VTABLE, immortal=True)
-
- tsize = cpu.sizeof(T, None)
- cdescr = cpu.fielddescrof(T, 'c')
- ddescr = cpu.fielddescrof(T, 'd')
- arraydescr3 = cpu.arraydescrof(lltype.GcArray(lltype.Ptr(NODE3)))
- U = lltype.GcStruct('U',
- ('parent', OBJECT),
- ('one', lltype.Ptr(lltype.GcArray(lltype.Ptr(NODE)))))
- u_vtable = lltype.malloc(OBJECT_VTABLE, immortal=True)
- u_vtable_adr = llmemory.cast_ptr_to_adr(u_vtable)
- SIMPLE = lltype.GcStruct('simple',
- ('parent', OBJECT),
- ('value', lltype.Signed))
- simplevalue = cpu.fielddescrof(SIMPLE, 'value')
- simple_vtable = lltype.malloc(OBJECT_VTABLE, immortal=True)
- simpledescr = cpu.sizeof(SIMPLE, simple_vtable)
- simple = lltype.malloc(SIMPLE, zero=True)
- simpleaddr = lltype.cast_opaque_ptr(llmemory.GCREF, simple)
- #usize = cpu.sizeof(U, ...)
- onedescr = cpu.fielddescrof(U, 'one')
- FUNC = lltype.FuncType([lltype.Signed], lltype.Signed)
- plaincalldescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT,
- EffectInfo.MOST_GENERAL)
- elidablecalldescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT,
- EffectInfo([valuedescr], [], [],
- [valuedescr], [], [],
- EffectInfo.EF_ELIDABLE_CANNOT_RAISE))
- elidable2calldescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT,
- EffectInfo([valuedescr], [], [],
- [valuedescr], [], [],
- EffectInfo.EF_ELIDABLE_OR_MEMORYERROR))
- elidable3calldescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT,
- EffectInfo([valuedescr], [], [],
- [valuedescr], [], [],
- EffectInfo.EF_ELIDABLE_CAN_RAISE))
- nonwritedescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT,
- EffectInfo([], [], [], [], [], []))
- writeadescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT,
- EffectInfo([], [], [], [adescr], [], []))
- writearraydescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT,
- EffectInfo([], [], [], [adescr], [arraydescr],
- []))
- writevalue3descr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT,
- EffectInfo([], [], [], [valuedescr3], [], []))
- readadescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT,
- EffectInfo([adescr], [], [], [], [], []))
- mayforcevirtdescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT,
- EffectInfo([nextdescr], [], [], [], [], [],
- EffectInfo.EF_FORCES_VIRTUAL_OR_VIRTUALIZABLE,
- can_invalidate=True))
- arraycopydescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT,
- EffectInfo([], [arraydescr], [], [], [arraydescr], [],
- EffectInfo.EF_CANNOT_RAISE,
- oopspecindex=EffectInfo.OS_ARRAYCOPY))
- raw_malloc_descr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT,
- EffectInfo([], [], [], [], [], [],
- EffectInfo.EF_CAN_RAISE,
- oopspecindex=EffectInfo.OS_RAW_MALLOC_VARSIZE_CHAR))
- raw_free_descr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT,
- EffectInfo([], [], [], [], [], [],
- EffectInfo.EF_CANNOT_RAISE,
- oopspecindex=EffectInfo.OS_RAW_FREE))
- chararray = lltype.GcArray(lltype.Char)
- chararraydescr = cpu.arraydescrof(chararray)
- u2array = lltype.GcArray(rffi.USHORT)
- u2arraydescr = cpu.arraydescrof(u2array)
- nodefull = lltype.malloc(NODE2, zero=True)
- nodefull.parent.next = lltype.cast_pointer(lltype.Ptr(NODE), nodefull)
- nodefull.parent.nexttuple = tpl
- nodefulladdr = lltype.cast_opaque_ptr(llmemory.GCREF, nodefull)
- # array of structs (complex data)
- complexarray = lltype.GcArray(
- lltype.Struct("complex",
- ("real", lltype.Float),
- ("imag", lltype.Float),
- )
- )
- complexarraydescr = cpu.arraydescrof(complexarray)
- complexrealdescr = cpu.interiorfielddescrof(complexarray, "real")
- compleximagdescr = cpu.interiorfielddescrof(complexarray, "imag")
- complexarraycopydescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT,
- EffectInfo([], [complexarraydescr], [], [], [complexarraydescr], [],
- EffectInfo.EF_CANNOT_RAISE,
- oopspecindex=EffectInfo.OS_ARRAYCOPY))
- rawarraydescr = cpu.arraydescrof(lltype.Array(lltype.Signed,
- hints={'nolength': True}))
- rawarraydescr_char = cpu.arraydescrof(lltype.Array(lltype.Char,
- hints={'nolength': True}))
- rawarraydescr_float = cpu.arraydescrof(lltype.Array(lltype.Float,
- hints={'nolength': True}))
- fc_array = lltype.GcArray(
- lltype.Struct(
- "floatchar", ("float", lltype.Float), ("char", lltype.Char)))
- fc_array_descr = cpu.arraydescrof(fc_array)
- fc_array_floatdescr = cpu.interiorfielddescrof(fc_array, "float")
- fc_array_chardescr = cpu.interiorfielddescrof(fc_array, "char")
- for _name, _os in [
- ('strconcatdescr', 'OS_STR_CONCAT'),
- ('strslicedescr', 'OS_STR_SLICE'),
- ('strequaldescr', 'OS_STR_EQUAL'),
- ('streq_slice_checknull_descr', 'OS_STREQ_SLICE_CHECKNULL'),
- ('streq_slice_nonnull_descr', 'OS_STREQ_SLICE_NONNULL'),
- ('streq_slice_char_descr', 'OS_STREQ_SLICE_CHAR'),
- ('streq_nonnull_descr', 'OS_STREQ_NONNULL'),
- ('streq_nonnull_char_descr', 'OS_STREQ_NONNULL_CHAR'),
- ('streq_checknull_char_descr', 'OS_STREQ_CHECKNULL_CHAR'),
- ('streq_lengthok_descr', 'OS_STREQ_LENGTHOK'),
- ]:
- if _name in ('strconcatdescr', 'strslicedescr'):
- _extra = EffectInfo.EF_ELIDABLE_OR_MEMORYERROR
- else:
- _extra = EffectInfo.EF_ELIDABLE_CANNOT_RAISE
- _oopspecindex = getattr(EffectInfo, _os)
- locals()[_name] = \
- cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT,
- EffectInfo([], [], [], [], [], [], _extra,
- oopspecindex=_oopspecindex))
- #
- _oopspecindex = getattr(EffectInfo, _os.replace('STR', 'UNI'))
- locals()[_name.replace('str', 'unicode')] = \
- cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT,
- EffectInfo([], [], [], [], [], [], _extra,
- oopspecindex=_oopspecindex))
- s2u_descr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT,
- EffectInfo([], [], [], [], [], [], EffectInfo.EF_ELIDABLE_CAN_RAISE,
- oopspecindex=EffectInfo.OS_STR2UNICODE))
- #
- class LoopToken(AbstractDescr):
- pass
- asmdescr = LoopToken() # it can be whatever, it's not a descr though
- from rpython.jit.metainterp.virtualref import VirtualRefInfo
- class FakeWarmRunnerDesc:
- pass
- FakeWarmRunnerDesc.cpu = cpu
- vrefinfo = VirtualRefInfo(FakeWarmRunnerDesc)
- virtualtokendescr = vrefinfo.descr_virtual_token
- virtualforceddescr = vrefinfo.descr_forced
- FUNC = lltype.FuncType([], lltype.Void)
- ei = EffectInfo([], [], [], [], [], [], EffectInfo.EF_CANNOT_RAISE,
- can_invalidate=False,
- oopspecindex=EffectInfo.OS_JIT_FORCE_VIRTUALIZABLE)
- clear_vable = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, ei)
- jit_virtual_ref_vtable = vrefinfo.jit_virtual_ref_vtable
- jvr_vtable_adr = llmemory.cast_ptr_to_adr(jit_virtual_ref_vtable)
- vref_descr = cpu.sizeof(vrefinfo.JIT_VIRTUAL_REF, jit_virtual_ref_vtable)
- FUNC = lltype.FuncType([lltype.Signed, lltype.Signed], lltype.Signed)
- ei = EffectInfo([], [], [], [], [], [], EffectInfo.EF_ELIDABLE_CANNOT_RAISE,
- can_invalidate=False,
- oopspecindex=EffectInfo.OS_INT_PY_DIV)
- int_py_div_descr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, ei)
- ei = EffectInfo([], [], [], [], [], [], EffectInfo.EF_ELIDABLE_CANNOT_RAISE,
- can_invalidate=False,
- oopspecindex=EffectInfo.OS_INT_UDIV)
- int_udiv_descr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, ei)
- ei = EffectInfo([], [], [], [], [], [], EffectInfo.EF_ELIDABLE_CANNOT_RAISE,
- can_invalidate=False,
- oopspecindex=EffectInfo.OS_INT_PY_MOD)
- int_py_mod_descr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, ei)
- namespace = locals()
- class FakeCallInfoCollection:
- def callinfo_for_oopspec(self, oopspecindex):
- calldescrtype = type(LLtypeMixin.strequaldescr)
- effectinfotype = type(LLtypeMixin.strequaldescr.get_extra_info())
- for value in LLtypeMixin.__dict__.values():
- if isinstance(value, calldescrtype):
- extra = value.get_extra_info()
- if (extra and isinstance(extra, effectinfotype) and
- extra.oopspecindex == oopspecindex):
- # returns 0 for 'func' in this test
- return value, 0
- raise AssertionError("not found: oopspecindex=%d" %
- oopspecindex)
- calldescr_udiv = LLtypeMixin.int_udiv_descr
- #calldescr_umod = LLtypeMixin.int_umod_descr
- LLtypeMixin.callinfocollection = FakeCallInfoCollection()
- # ____________________________________________________________
- class Fake(object):
- failargs_limit = 1000
- storedebug = None
- class FakeWarmState(object):
- vec = True # default is on
- vec_all = False
- vec_cost = 0
- def __init__(self, enable_opts):
- self.enable_opts = enable_opts
- class FakeJitDriverStaticData(object):
- vec = False
- class FakeMetaInterpStaticData(object):
- all_descrs = []
- def __init__(self, cpu):
- self.cpu = cpu
- self.profiler = EmptyProfiler()
- self.options = Fake()
- self.globaldata = Fake()
- self.config = get_combined_translation_config(translating=True)
- self.jitlog = jl.JitLogger()
- class logger_noopt:
- @classmethod
- def log_loop(*args, **kwds):
- pass
- @classmethod
- def log_loop_from_trace(*args, **kwds):
- pass
- class logger_ops:
- repr_of_resop = repr
- class warmrunnerdesc:
- class memory_manager:
- retrace_limit = 5
- max_retrace_guards = 15
- jitcounter = DeterministicJitCounter()
- def get_name_from_address(self, addr):
- # hack
- try:
- return "".join(addr.ptr.name.chars)
- except AttributeError:
- return ""
- class Info(object):
- def __init__(self, preamble, short_preamble=None, virtual_state=None):
- self.preamble = preamble
- self.short_preamble = short_preamble
- self.virtual_state = virtual_state
- class Storage(compile.ResumeGuardDescr):
- "for tests."
- def __init__(self, metainterp_sd=None, original_greenkey=None):
- self.metainterp_sd = metainterp_sd
- self.original_greenkey = original_greenkey
- def store_final_boxes(self, op, boxes, metainterp_sd):
- op.setfailargs(boxes)
- def __eq__(self, other):
- return True # screw this
- #return type(self) is type(other) # xxx obscure
- def _sortboxes(boxes):
- _kind2count = {history.INT: 1, history.REF: 2, history.FLOAT: 3}
- return sorted(boxes, key=lambda box: _kind2count[box.type])
- final_descr = history.BasicFinalDescr()
- class BaseTest(object):
- def parse(self, s, boxkinds=None, want_fail_descr=True, postprocess=None):
- AbstractValue._repr_memo.counter = 0
- self.oparse = OpParser(s, self.cpu, self.namespace, boxkinds,
- None, False, postprocess)
- return self.oparse.parse()
- def add_guard_future_condition(self, res):
- # invent a GUARD_FUTURE_CONDITION to not have to change all tests
- if res.operations[-1].getopnum() == rop.JUMP:
- guard = ResOperation(rop.GUARD_FUTURE_CONDITION, [])
- res.operations.insert(-1, guard)
- @staticmethod
- def assert_equal(optimized, expected, text_right=None):
- from rpython.jit.metainterp.optimizeopt.util import equaloplists
- assert len(optimized.inputargs) == len(expected.inputargs)
- remap = {}
- for box1, box2 in zip(optimized.inputargs, expected.inputargs):
- assert box1.type == box2.type
- remap[box2] = box1
- assert equaloplists(optimized.operations,
- expected.operations, False, remap, text_right)
- def _do_optimize_loop(self, compile_data):
- from rpython.jit.metainterp.optimizeopt import optimize_trace
- metainterp_sd = FakeMetaInterpStaticData(self.cpu)
- if hasattr(self, 'vrefinfo'):
- metainterp_sd.virtualref_info = self.vrefinfo
- if hasattr(self, 'callinfocollection'):
- metainterp_sd.callinfocollection = self.callinfocollection
- compute_bitstrings(self.cpu.fetch_all_descrs())
- #
- compile_data.enable_opts = self.enable_opts
- state = optimize_trace(metainterp_sd, None, compile_data)
- return state
- def _convert_call_pure_results(self, d):
- from rpython.jit.metainterp.optimizeopt.util import args_dict
- if d is None:
- return
- call_pure_results = args_dict()
- for k, v in d.items():
- call_pure_results[list(k)] = v
- return call_pure_results
- def convert_values(self, inpargs, values):
- from rpython.jit.metainterp.history import IntFrontendOp, RefFrontendOp
- if values:
- r = []
- for arg, v in zip(inpargs, values):
- if arg.type == 'i':
- n = IntFrontendOp(0)
- if v is not None:
- n.setint(v)
- else:
- n = RefFrontendOp(0)
- if v is not None:
- n.setref_base(v)
- assert arg.type == 'r'
- r.append(n)
- return r
- return inpargs
- def unroll_and_optimize(self, loop, call_pure_results=None,
- jump_values=None):
- self.add_guard_future_condition(loop)
- jump_op = loop.operations[-1]
- assert jump_op.getopnum() == rop.JUMP
- celltoken = JitCellToken()
- runtime_boxes = self.pack_into_boxes(jump_op, jump_values)
- jump_op.setdescr(celltoken)
- #start_label = ResOperation(rop.LABEL, loop.inputargs,
- # descr=jump_op.getdescr())
- #end_label = jump_op.copy_and_change(opnum=rop.LABEL)
- call_pure_results = self._convert_call_pure_results(call_pure_results)
- t = convert_loop_to_trace(loop, FakeMetaInterpStaticData(self.cpu))
- preamble_data = compile.LoopCompileData(t, runtime_boxes,
- call_pure_results)
- start_state, preamble_ops = self._do_optimize_loop(preamble_data)
- preamble_data.forget_optimization_info()
- loop_data = compile.UnrolledLoopData(preamble_data.trace,
- celltoken, start_state, call_pure_results)
- loop_info, ops = self._do_optimize_loop(loop_data)
- preamble = TreeLoop('preamble')
- preamble.inputargs = start_state.renamed_inputargs
- start_label = ResOperation(rop.LABEL, start_state.renamed_inputargs)
- preamble.operations = ([start_label] + preamble_ops +
- loop_info.extra_same_as + [loop_info.label_op])
- loop.inputargs = loop_info.label_op.getarglist()[:]
- loop.operations = [loop_info.label_op] + ops
- return Info(preamble, loop_info.target_token.short_preamble,
- start_state.virtual_state)
- def pack_into_boxes(self, jump_op, jump_values):
- assert jump_op.getopnum() == rop.JUMP
- r = []
- if jump_values is not None:
- assert len(jump_values) == len(jump_op.getarglist())
- for i, v in enumerate(jump_values):
- if v is not None:
- r.append(InputArgRef(v))
- else:
- r.append(None)
- else:
- for i, box in enumerate(jump_op.getarglist()):
- if box.type == 'r' and not box.is_constant():
- # NOTE: we arbitrarily set the box contents to a NODE2
- # object here. If you need something different, you
- # need to pass a 'jump_values' argument to e.g.
- # optimize_loop()
- r.append(InputArgRef(self.nodefulladdr))
- else:
- r.append(None)
- return r
- class FakeDescr(compile.ResumeGuardDescr):
- def clone_if_mutable(self):
- return FakeDescr()
- def __eq__(self, other):
- return isinstance(other, FakeDescr)
- def convert_old_style_to_targets(loop, jump):
- newloop = TreeLoop(loop.name)
- newloop.inputargs = loop.inputargs
- newloop.operations = [ResOperation(rop.LABEL, loop.inputargs, descr=FakeDescr())] + \
- loop.operations
- if not jump:
- assert newloop.operations[-1].getopnum() == rop.JUMP
- newloop.operations[-1] = newloop.operations[-1].copy_and_change(
- rop.LABEL)
- return newloop
- # ____________________________________________________________