def test_fixed_getitem_foldable(): builtin_test( 'list.getitem_foldable/NONNEG', [varoftype(FIXEDLIST), varoftype(lltype.Signed)], lltype.Void, "") builtin_test( 'list.getitem_foldable/NEG', [varoftype(FIXEDLIST), varoftype(lltype.Signed)], lltype.Void, "")
def test_no_gcstruct_nesting_outside_of_OBJECT(): PARENT = lltype.GcStruct("parent") STRUCT = lltype.GcStruct("struct", ("parent", PARENT), ("x", lltype.Signed)) v_x = varoftype(lltype.Ptr(STRUCT)) op = SpaceOperation("getfield", [v_x, Constant("x", lltype.Void)], varoftype(lltype.Signed)) tr = Transformer(None, None) py.test.raises(NotImplementedError, tr.rewrite_operation, op)
def make_dispatcher(self, shape, index, argtypes, resulttype): inputargs = [varoftype(t) for t in [Char] + argtypes] startblock = Block(inputargs) startblock.exitswitch = inputargs[0] graph = FunctionGraph("dispatcher", startblock, varoftype(resulttype)) row_of_graphs = self.callfamily.calltables[shape][index] links = [] descs = list(self.s_pbc.descriptions) if self.s_pbc.can_be_None: descs.insert(0, None) for desc in descs: if desc is None: continue args_v = [varoftype(t) for t in argtypes] b = Block(args_v) llfn = self.rtyper.getcallable(row_of_graphs[desc]) v_fn = inputconst(typeOf(llfn), llfn) v_result = varoftype(resulttype) b.operations.append( SpaceOperation("direct_call", [v_fn] + args_v, v_result)) b.closeblock(Link([v_result], graph.returnblock)) i = self.descriptions.index(desc) links.append(Link(inputargs[1:], b, chr(i))) links[-1].llexitcase = chr(i) startblock.closeblock(*links) return graph
def dispatcher(self, shape, index, argtypes, resulttype): key = shape, index, tuple(argtypes), resulttype if key in self._dispatch_cache: return self._dispatch_cache[key] from rpython.translator.unsimplify import varoftype from rpython.flowspace.model import FunctionGraph, Link, Block, SpaceOperation inputargs = [varoftype(t) for t in [Char] + argtypes] startblock = Block(inputargs) startblock.exitswitch = inputargs[0] graph = FunctionGraph("dispatcher", startblock, varoftype(resulttype)) row_of_graphs = self.callfamily.calltables[shape][index] links = [] descs = list(self.s_pbc.descriptions) if self.s_pbc.can_be_None: descs.insert(0, None) for desc in descs: if desc is None: continue args_v = [varoftype(t) for t in argtypes] b = Block(args_v) llfn = self.rtyper.getcallable(row_of_graphs[desc]) v_fn = inputconst(typeOf(llfn), llfn) v_result = varoftype(resulttype) b.operations.append( SpaceOperation("direct_call", [v_fn] + args_v, v_result)) b.closeblock(Link([v_result], graph.returnblock)) i = self.descriptions.index(desc) links.append(Link(inputargs[1:], b, chr(i))) links[-1].llexitcase = chr(i) startblock.closeblock(*links) self.rtyper.annotator.translator.graphs.append(graph) ll_ret = getfunctionptr(graph) #FTYPE = FuncType c_ret = self._dispatch_cache[key] = inputconst(typeOf(ll_ret), ll_ret) return c_ret
def do_check(self, opname, oopspecindex, ARGS, RESULT): vlist = [varoftype(ARG) for ARG in ARGS] v_result = varoftype(RESULT) op = SpaceOperation(opname, vlist, v_result) tr = Transformer(FakeCPU(), FakeBuiltinCallControl()) op1 = tr.rewrite_operation(op) if isinstance(op1, list): [op1] = op1 # def is_llf(TYPE): return (TYPE == lltype.SignedLongLong or TYPE == lltype.UnsignedLongLong or TYPE == lltype.Float) if is_llf(RESULT): assert op1.opname == 'residual_call_irf_f' else: assert op1.opname == 'residual_call_irf_i' gotindex = getattr(EffectInfo, 'OS_' + op1.args[0].value.upper().lstrip('U')) assert gotindex == oopspecindex assert list( op1.args[1]) == [v for v in vlist if not is_llf(v.concretetype)] assert list(op1.args[2]) == [] assert list( op1.args[3]) == [v for v in vlist if is_llf(v.concretetype)] assert op1.args[4] == 'calldescr-%d' % oopspecindex assert op1.result == v_result
def test_symmetric(): ops = { "int_add": "int_add", "int_or": "int_or", "int_gt": ("int_gt", "int_lt"), "uint_eq": "int_eq", "uint_le": ("uint_le", "uint_ge"), "char_ne": "int_ne", "char_lt": ("int_lt", "int_gt"), "uint_xor": "int_xor", "float_mul": "float_mul", "float_gt": ("float_gt", "float_lt"), } v3 = varoftype(lltype.Signed) for v1 in [varoftype(lltype.Signed), const(42)]: for v2 in [varoftype(lltype.Signed), const(43)]: for name1, name2 in ops.items(): op = SpaceOperation(name1, [v1, v2], v3) op1 = Transformer(FakeCPU()).rewrite_operation(op) if isinstance(name2, str): name2 = name2, name2 if isinstance(v1, Constant) and isinstance(v2, Variable): assert op1.args == [v2, v1] assert op1.result == v3 assert op1.opname == name2[1] else: assert op1.args == [v1, v2] assert op1.result == v3 assert op1.opname == name2[0]
def test_setfield(): # XXX a more compact encoding would be possible; see test_getfield() S1 = lltype.Struct("S1") S2 = lltype.GcStruct("S2") S = lltype.GcStruct( "S", ("int", lltype.Signed), ("ps1", lltype.Ptr(S1)), ("ps2", lltype.Ptr(S2)), ("flt", lltype.Float), ("boo", lltype.Bool), ("chr", lltype.Char), ("unc", lltype.UniChar), ) for name, suffix in [ ("int", "i"), ("ps1", "i"), ("ps2", "r"), ("flt", "f"), ("boo", "i"), ("chr", "i"), ("unc", "i"), ]: v_parent = varoftype(lltype.Ptr(S)) c_name = Constant(name, lltype.Void) v_newvalue = varoftype(getattr(S, name)) op = SpaceOperation("setfield", [v_parent, c_name, v_newvalue], varoftype(lltype.Void)) op1 = Transformer(FakeCPU()).rewrite_operation(op) assert op1.opname == "setfield_gc_" + suffix fielddescr = ("fielddescr", S, name) assert op1.args == [v_parent, v_newvalue, fielddescr] assert op1.result is None
def test_resizable_getitem(): builtin_test('list.getitem/NONNEG', [varoftype(VARLIST), varoftype(lltype.Signed)], lltype.Void, "") builtin_test('list.getitem/NEG', [varoftype(VARLIST), varoftype(lltype.Signed)], lltype.Void, "")
def test_is_true(self): for opname, T in [('llong_is_true', lltype.SignedLongLong), ('ullong_is_true', lltype.UnsignedLongLong)]: v = varoftype(T) v_result = varoftype(lltype.Bool) op = SpaceOperation(opname, [v], v_result) tr = Transformer(FakeCPU(), FakeBuiltinCallControl()) oplist = tr.rewrite_operation(op) assert len(oplist) == 2 assert oplist[0].opname == 'residual_call_irf_f' assert oplist[0].args[0].value == opname.split( '_')[0] + '_from_int' assert list(oplist[0].args[1]) == [const(0)] assert list(oplist[0].args[2]) == [] assert list(oplist[0].args[3]) == [] assert oplist[0].args[4] == 'calldescr-84' v_x = oplist[0].result assert isinstance(v_x, Variable) assert v_x.concretetype is T assert oplist[1].opname == 'residual_call_irf_i' assert oplist[1].args[0].value == 'llong_ne' assert list(oplist[1].args[1]) == [] assert list(oplist[1].args[2]) == [] assert list(oplist[1].args[3]) == [v, v_x] assert oplist[1].args[4] == 'calldescr-76' assert oplist[1].result == v_result
def do_check(self, opname, oopspecindex, ARGS, RESULT): vlist = [varoftype(ARG) for ARG in ARGS] v_result = varoftype(RESULT) op = SpaceOperation(opname, vlist, v_result) tr = Transformer(FakeCPU(), FakeBuiltinCallControl()) op1 = tr.rewrite_operation(op) if isinstance(op1, list): [op1] = op1 # def is_llf(TYPE): return (TYPE == lltype.SignedLongLong or TYPE == lltype.UnsignedLongLong or TYPE == lltype.Float) if is_llf(RESULT): assert op1.opname == 'residual_call_irf_f' else: assert op1.opname == 'residual_call_irf_i' gotindex = getattr(EffectInfo, 'OS_' + op1.args[0].value.upper().lstrip('U')) assert gotindex == oopspecindex assert list(op1.args[1]) == [v for v in vlist if not is_llf(v.concretetype)] assert list(op1.args[2]) == [] assert list(op1.args[3]) == [v for v in vlist if is_llf(v.concretetype)] assert op1.args[4] == 'calldescr-%d' % oopspecindex assert op1.result == v_result
def test_graphs_from_no_target(): cc = CallControl() F = lltype.FuncType([], lltype.Signed) v = varoftype(lltype.Signed) op = SpaceOperation("indirect_call", [varoftype(lltype.Ptr(F)), Constant(None, lltype.Void)], v) lst = cc.graphs_from(op, {}.__contains__) assert lst is None
def test_resizable_getitem(): builtin_test( 'list.getitem/NONNEG', [varoftype(VARLIST), varoftype(lltype.Signed)], lltype.Void, "") builtin_test( 'list.getitem/NEG', [varoftype(VARLIST), varoftype(lltype.Signed)], lltype.Void, "")
def test_is_true(self): for opname, T in [('llong_is_true', lltype.SignedLongLong), ('ullong_is_true', lltype.UnsignedLongLong)]: v = varoftype(T) v_result = varoftype(lltype.Bool) op = SpaceOperation(opname, [v], v_result) tr = Transformer(FakeCPU(), FakeBuiltinCallControl()) oplist = tr.rewrite_operation(op) assert len(oplist) == 2 assert oplist[0].opname == 'residual_call_irf_f' assert oplist[0].args[0].value == opname.split('_')[0]+'_from_int' assert list(oplist[0].args[1]) == [const(0)] assert list(oplist[0].args[2]) == [] assert list(oplist[0].args[3]) == [] assert oplist[0].args[4] == 'calldescr-84' v_x = oplist[0].result assert isinstance(v_x, Variable) assert v_x.concretetype is T assert oplist[1].opname == 'residual_call_irf_i' assert oplist[1].args[0].value == 'llong_ne' assert list(oplist[1].args[1]) == [] assert list(oplist[1].args[2]) == [] assert list(oplist[1].args[3]) == [v, v_x] assert oplist[1].args[4] == 'calldescr-76' assert oplist[1].result == v_result
def test_nongc_ptr_eq(): v1 = varoftype(rclass.NONGCOBJECTPTR) v2 = varoftype(rclass.NONGCOBJECTPTR) v3 = varoftype(lltype.Bool) c0 = const(lltype.nullptr(rclass.NONGCOBJECT)) # for opname, reducedname in [("ptr_eq", "int_is_zero"), ("ptr_ne", "int_is_true")]: op = SpaceOperation(opname, [v1, v2], v3) op1 = Transformer().rewrite_operation(op) assert op1.opname == opname.replace("ptr_", "int_") assert op1.args == [v1, v2] # op = SpaceOperation(opname, [v1, c0], v3) op1 = Transformer().rewrite_operation(op) assert op1.opname == reducedname assert op1.args == [v1] # op = SpaceOperation(opname, [c0, v2], v3) op1 = Transformer().rewrite_operation(op) assert op1.opname == reducedname assert op1.args == [v2] # op = SpaceOperation("ptr_iszero", [v1], v3) op1 = Transformer().rewrite_operation(op) assert op1.opname == "int_is_zero" assert op1.args == [v1] # op = SpaceOperation("ptr_nonzero", [v1], v3) op1 = Transformer().rewrite_operation(op) assert op1.opname == "int_is_true" assert op1.args == [v1]
def test_fixed_ll_arraymove(): builtin_test('list.ll_arraymove', [ varoftype(FIXEDLIST), varoftype(lltype.Signed), varoftype(lltype.Signed), varoftype(lltype.Signed) ], lltype.Void, NotSupported)
def test_fixed_getitem_foldable(): builtin_test('list.getitem_foldable/NONNEG', [varoftype(FIXEDLIST), varoftype(lltype.Signed)], lltype.Void, "") builtin_test('list.getitem_foldable/NEG', [varoftype(FIXEDLIST), varoftype(lltype.Signed)], lltype.Void, "")
def test_getfield(): # XXX a more compact encoding would be possible, something along # the lines of getfield_gc_r %r0, $offset, %r1 # which would not need a Descr at all. S1 = lltype.Struct("S1") S2 = lltype.GcStruct("S2") S = lltype.GcStruct( "S", ("int", lltype.Signed), ("ps1", lltype.Ptr(S1)), ("ps2", lltype.Ptr(S2)), ("flt", lltype.Float), ("boo", lltype.Bool), ("chr", lltype.Char), ("unc", lltype.UniChar), ) for name, suffix in [ ("int", "i"), ("ps1", "i"), ("ps2", "r"), ("flt", "f"), ("boo", "i"), ("chr", "i"), ("unc", "i"), ]: v_parent = varoftype(lltype.Ptr(S)) c_name = Constant(name, lltype.Void) v_result = varoftype(getattr(S, name)) op = SpaceOperation("getfield", [v_parent, c_name], v_result) op1 = Transformer(FakeCPU()).rewrite_operation(op) assert op1.opname == "getfield_gc_" + suffix fielddescr = ("fielddescr", S, name) assert op1.args == [v_parent, fielddescr] assert op1.result == v_result
def test_unicode_getinteriorarraysize(): v = varoftype(lltype.Ptr(rstr.UNICODE)) v_result = varoftype(lltype.Signed) op = SpaceOperation("getinteriorarraysize", [v, Constant("chars", lltype.Void)], v_result) op1 = Transformer().rewrite_operation(op) assert op1.opname == "unicodelen" assert op1.args == [v] assert op1.result == v_result
def test_raw_malloc_unsupported_flag(): S = rffi.CArray(lltype.Signed) v1 = varoftype(lltype.Signed) v = varoftype(lltype.Ptr(S)) flags = Constant({"flavor": "raw", "unsupported_flag": True}, lltype.Void) op = SpaceOperation("malloc_varsize", [Constant(S, lltype.Void), flags, v1], v) tr = Transformer(FakeCPU(), FakeResidualCallControl()) py.test.raises(UnsupportedMallocFlags, tr.rewrite_operation, op)
def get_direct_call_op(argtypes, restype): FUNC = lltype.FuncType(argtypes, restype) fnptr = lltype.functionptr(FUNC, "g") # no graph c_fnptr = const(fnptr) vars = [varoftype(TYPE) for TYPE in argtypes] v_result = varoftype(restype) op = SpaceOperation("direct_call", [c_fnptr] + vars, v_result) return op
def test_write_barrier_support_setfield(): PTR_TYPE2 = lltype.Ptr(lltype.GcStruct('T', ('y', lltype.Signed))) PTR_TYPE = lltype.Ptr(lltype.GcStruct('S', ('x', PTR_TYPE2))) write_barrier_check(SpaceOperation( "setfield", [varoftype(PTR_TYPE), Constant('x', lltype.Void), varoftype(PTR_TYPE2)], varoftype(lltype.Void)))
def test_write_barrier_support_setarrayitem(): PTR_TYPE2 = lltype.Ptr(lltype.GcStruct('T', ('y', lltype.Signed))) ARRAYPTR = lltype.Ptr(lltype.GcArray(PTR_TYPE2)) write_barrier_check(SpaceOperation( "setarrayitem", [varoftype(ARRAYPTR), varoftype(lltype.Signed), varoftype(PTR_TYPE2)], varoftype(lltype.Void)))
def test_dont_add_write_barrier_for_constant_new_value(): PTR_TYPE2 = lltype.Ptr(lltype.GcStruct('T', ('y', lltype.Signed))) PTR_TYPE = lltype.Ptr(lltype.GcStruct('S', ('x', PTR_TYPE2))) write_barrier_check(SpaceOperation( "setfield", [varoftype(PTR_TYPE), Constant('x', lltype.Void), Constant('foo', varoftype(PTR_TYPE2))], varoftype(lltype.Void)), needs_write_barrier=False)
def test_unicode_getinteriorfield(): v = varoftype(lltype.Ptr(rstr.UNICODE)) v_index = varoftype(lltype.Signed) v_result = varoftype(lltype.UniChar) op = SpaceOperation("getinteriorfield", [v, Constant("chars", lltype.Void), v_index], v_result) op1 = Transformer().rewrite_operation(op) assert op1.opname == "unicodegetitem" assert op1.args == [v, v_index] assert op1.result == v_result
def test_fixed_ll_arraycopy(): builtin_test('list.ll_arraycopy', [varoftype(FIXEDLIST), varoftype(FIXEDLIST), varoftype(lltype.Signed), varoftype(lltype.Signed), varoftype(lltype.Signed)], lltype.Void, NotSupported)
def test_double_promote_nonstr(): v1 = varoftype(lltype.Signed) v2 = varoftype(lltype.Signed) tr = Transformer(FakeCPU(), FakeBuiltinCallControl()) op1 = SpaceOperation("hint", [v1, Constant({"promote": True}, lltype.Void)], v2) op2 = SpaceOperation("hint", [v1, Constant({"promote_string": True, "promote": True}, lltype.Void)], v2) lst1 = tr.rewrite_operation(op1) lst2 = tr.rewrite_operation(op2) assert lst1 == lst2
def test_getfield_gc_pure(): S = lltype.GcStruct("S", ("x", lltype.Char), hints={"immutable": True}) v1 = varoftype(lltype.Ptr(S)) v2 = varoftype(lltype.Char) op = SpaceOperation("getfield", [v1, Constant("x", lltype.Void)], v2) op1 = Transformer(FakeCPU()).rewrite_operation(op) assert op1.opname == "getfield_gc_i_pure" assert op1.args == [v1, ("fielddescr", S, "x")] assert op1.result == v2
def test_raw_free_no_track_allocation(): S = rffi.CArray(lltype.Signed) flags = Constant({"flavor": "raw", "track_allocation": False}, lltype.Void) op = SpaceOperation("free", [varoftype(lltype.Ptr(S)), flags], varoftype(lltype.Void)) tr = Transformer(FakeCPU(), FakeResidualCallControl()) op0, op1 = tr.rewrite_operation(op) assert op0.opname == "residual_call_ir_v" assert op0.args[0].value == "raw_free_no_track_allocation" assert op1.opname == "-live-"
def test_raw_free(): S = rffi.CArray(lltype.Char) flags = Constant({"flavor": "raw", "track_allocation": True}, lltype.Void) op = SpaceOperation("free", [varoftype(lltype.Ptr(S)), flags], varoftype(lltype.Void)) tr = Transformer(FakeCPU(), FakeBuiltinCallControl()) op0 = tr.rewrite_operation(op) assert op0.opname == "residual_call_ir_v" assert op0.args[0].value == "raw_free" assert op0.args[-1] == "calldescr-%d" % effectinfo.EffectInfo.OS_RAW_FREE
def test_write_barrier_support_setinteriorfield(): PTR_TYPE2 = lltype.Ptr(lltype.GcStruct('T', ('y', lltype.Signed))) ARRAYPTR2 = lltype.Ptr(lltype.GcArray(('a', lltype.Signed), ('b', PTR_TYPE2))) write_barrier_check(SpaceOperation( "setinteriorfield", [varoftype(ARRAYPTR2), varoftype(lltype.Signed), Constant('b', lltype.Void), varoftype(PTR_TYPE2)], varoftype(lltype.Void)))
def test_int_abs(): v1 = varoftype(lltype.Signed) v2 = varoftype(lltype.Signed) op = SpaceOperation("int_abs", [v1], v2) tr = Transformer(FakeCPU(), FakeRegularCallControl()) tr.graph = "somemaingraph" oplist = tr.rewrite_operation(op) assert oplist[0].opname == "inline_call_ir_i" assert oplist[0].args[0] == "somejitcode"
def test_fixed_ll_arraymove(): builtin_test('list.ll_arraymove', [varoftype(FIXEDLIST), varoftype(lltype.Signed), varoftype(lltype.Signed), varoftype(lltype.Signed)], lltype.Void, """ residual_call_ir_v $'myfunc', I[%i0, %i1, %i2], R[%r0], <CallDescrOS9> """)
def test_str_newstr(): c_STR = Constant(rstr.STR, lltype.Void) c_flavor = Constant({"flavor": "gc"}, lltype.Void) v1 = varoftype(lltype.Signed) v2 = varoftype(lltype.Ptr(rstr.STR)) op = SpaceOperation("malloc_varsize", [c_STR, c_flavor, v1], v2) op1 = Transformer().rewrite_operation(op) assert op1.opname == "newstr" assert op1.args == [v1] assert op1.result == v2
def test_graphs_from_no_target(): cc = CallControl() F = lltype.FuncType([], lltype.Signed) v = varoftype(lltype.Signed) op = SpaceOperation( 'indirect_call', [varoftype(lltype.Ptr(F)), Constant(None, lltype.Void)], v) lst = cc.graphs_from(op, {}.__contains__) assert lst is None
def test_str_setinteriorfield(): v = varoftype(lltype.Ptr(rstr.STR)) v_index = varoftype(lltype.Signed) v_newchr = varoftype(lltype.Char) v_void = varoftype(lltype.Void) op = SpaceOperation("setinteriorfield", [v, Constant("chars", lltype.Void), v_index, v_newchr], v_void) op1 = Transformer().rewrite_operation(op) assert op1.opname == "strsetitem" assert op1.args == [v, v_index, v_newchr] assert op1.result == v_void
def test_fixed_ll_arraycopy(): builtin_test('list.ll_arraycopy', [varoftype(FIXEDLIST), varoftype(FIXEDLIST), varoftype(lltype.Signed), varoftype(lltype.Signed), varoftype(lltype.Signed)], lltype.Void, """ residual_call_ir_v $'myfunc', I[%i0, %i1, %i2], R[%r0, %r1], <CallDescrOS1> """)
def test_raw_load(): v_storage = varoftype(llmemory.Address) v_index = varoftype(lltype.Signed) v_res = varoftype(lltype.Signed) # for example op = SpaceOperation("raw_load", [v_storage, v_index], v_res) op1 = Transformer(FakeCPU()).rewrite_operation(op) assert op1.opname == "raw_load_i" assert op1.args[0] == v_storage assert op1.args[1] == v_index assert op1.args[2] == ("arraydescr", rffi.CArray(lltype.Signed)) assert op1.result == v_res
def test_fixed_getitem_foldable(): builtin_test('list.getitem_foldable/NONNEG', [varoftype(FIXEDLIST), varoftype(lltype.Signed)], lltype.Signed, """ getarrayitem_gc_i_pure %r0, %i0, <ArrayDescr> -> %i1 """) builtin_test('list.getitem_foldable/NEG', [varoftype(FIXEDLIST), varoftype(lltype.Signed)], lltype.Signed, """ -live- check_neg_index %r0, %i0, <ArrayDescr> -> %i1 getarrayitem_gc_i_pure %r0, %i1, <ArrayDescr> -> %i2 """)
def test_resizable_getitem(): builtin_test('list.getitem/NONNEG', [varoftype(VARLIST), varoftype(lltype.Signed)], lltype.Signed, """ getlistitem_gc_i %r0, %i0, <FieldDescr items>, <ArrayDescr> -> %i1 """) builtin_test('list.getitem/NEG', [varoftype(VARLIST), varoftype(lltype.Signed)], lltype.Signed, """ -live- check_resizable_neg_index %r0, %i0, <FieldDescr length> -> %i1 getlistitem_gc_i %r0, %i1, <FieldDescr items>, <ArrayDescr> -> %i2 """)
def test_resizable_newlist(): builtin_test('newlist', [], VARLIST, NotSupported) builtin_test('newlist', [Constant(5, lltype.Signed)], VARLIST, NotSupported) builtin_test('newlist', [varoftype(lltype.Signed)], VARLIST, NotSupported) builtin_test('newlist', [Constant(5, lltype.Signed), Constant(0, lltype.Signed)], VARLIST, NotSupported) builtin_test('newlist', [Constant(5, lltype.Signed), Constant(1, lltype.Signed)], VARLIST, NotSupported) builtin_test('newlist', [Constant(5, lltype.Signed), varoftype(lltype.Signed)], VARLIST, NotSupported)
def test_constants(self): for TYPE in [lltype.SignedLongLong, lltype.UnsignedLongLong]: v_x = varoftype(TYPE) vlist = [v_x, const(rffi.cast(TYPE, 7))] v_result = varoftype(TYPE) op = SpaceOperation('llong_add', vlist, v_result) tr = Transformer(FakeCPU(), FakeBuiltinCallControl()) op1 = tr.rewrite_operation(op) # assert op1.opname == 'residual_call_irf_f' assert list(op1.args[1]) == [] assert list(op1.args[2]) == [] assert list(op1.args[3]) == vlist assert op1.result == v_result
def test_arg_sublist_1(self): v1 = varoftype(lltype.Signed) v2 = varoftype(lltype.Char) v3 = varoftype(rclass.OBJECTPTR) v4 = varoftype(lltype.Ptr(rstr.STR)) v5 = varoftype(lltype.Float) op = SpaceOperation('residual_call_ir_f', [Constant(12345, lltype.Signed), # function ptr ListOfKind('int', [v1, v2]), # int args ListOfKind('ref', [v3, v4])], # ref args v5) # result flattener = GraphFlattener(None, fake_regallocs()) flattener.serialize_op(op) assert_format(flattener.ssarepr, """ residual_call_ir_f $12345, I[%i0, %i1], R[%r0, %r1] -> %f0 """)
def builtin_test(oopspec_name, args, RESTYPE, expected): v_result = varoftype(RESTYPE) tr = Transformer(FakeCPU(), FakeCallControl()) tr.immutable_arrays = {} tr.vable_array_vars = {} if '/' in oopspec_name: oopspec_name, property = oopspec_name.split('/') def force_flags(op): if property == 'NONNEG': return True if property == 'NEG': return False raise ValueError(property) tr._get_list_nonneg_canraise_flags = force_flags op = SpaceOperation('direct_call', [Constant("myfunc", lltype.Void)] + args, v_result) try: oplist = tr._handle_list_call(op, oopspec_name, args) except NotSupported: assert expected is NotSupported else: assert expected is not NotSupported assert oplist is not None flattener = GraphFlattener(None, fake_regallocs()) if not isinstance(oplist, list): oplist = [oplist] for op1 in oplist: flattener.serialize_op(op1) assert_format(flattener.ssarepr, expected)
def insert_along_link(link, opname, args, cache): b2 = link.target if b2 not in cache: newblock = Block([v.copy() for v in b2.inputargs]) newblock.operations.append( SpaceOperation(opname, args, varoftype(lltype.Void))) newblock.closeblock(Link(list(newblock.inputargs), b2)) cache[b2] = newblock link.target = cache[b2]
def test_graphs_from_indirect_call(): cc = CallControl() F = lltype.FuncType([], lltype.Signed) v = varoftype(lltype.Signed) graphlst = ['f1graph', 'f2graph'] op = SpaceOperation( 'indirect_call', [varoftype(lltype.Ptr(F)), Constant(graphlst, lltype.Void)], v) # lst = cc.graphs_from(op, {'f1graph': True, 'f2graph': True}.__contains__) assert lst == ['f1graph', 'f2graph'] # normal indirect call # lst = cc.graphs_from(op, {'f1graph': True}.__contains__) assert lst == ['f1graph'] # indirect call, look only inside some graphs # lst = cc.graphs_from(op, {}.__contains__) assert lst is None # indirect call, don't look inside any graph
def _fix_graph_after_inlining(graph, initial_block, initial_index): op = initial_block.operations.pop(initial_index) assert op.opname == 'gc_push_roots' seen = set() pending = [(initial_block, initial_index, op.args)] while pending: block, start_index, track_args = pending.pop() if block in seen: continue seen.add(block) assert block.operations != () # did not find the gc_pop_roots? new_operations = block.operations[:start_index] stop = False for i in range(start_index, len(block.operations)): op = block.operations[i] if op.opname == 'gc_push_roots': raise Exception("%r: seems to have inlined inside it another " "graph which also uses GC roots" % (graph,)) if op.opname == 'gc_pop_roots': # end of the inlined graph, drop gc_pop_roots, keep the tail new_operations += block.operations[i + 1:] stop = True break if op.opname in ('direct_call', 'indirect_call'): new_operations.append(SpaceOperation('gc_push_roots', track_args[:], varoftype(lltype.Void))) new_operations.append(op) new_operations.append(SpaceOperation('gc_pop_roots', track_args[:], varoftype(lltype.Void))) else: new_operations.append(op) block.operations = new_operations if not stop: for link in block.exits: track_next = [] for v in track_args: if not isinstance(v, Variable): continue i = link.args.index(v) # should really be here w = link.target.inputargs[i] track_next.append(w) pending.append((link.target, 0, track_next))
def test_newlist(): builtin_test('newlist', [], FIXEDLIST, """new_array $0, <ArrayDescr> -> %r0""") builtin_test('newlist', [Constant(5, lltype.Signed)], FIXEDLIST, """new_array $5, <ArrayDescr> -> %r0""") builtin_test('newlist', [varoftype(lltype.Signed)], FIXEDLIST, """new_array %i0, <ArrayDescr> -> %r0""") builtin_test('newlist_clear', [Constant(5, lltype.Signed)], FIXEDLIST, """new_array_clear $5, <ArrayDescr> -> %r0""") builtin_test('newlist', [], FIXEDPTRLIST, """new_array_clear $0, <ArrayDescr> -> %r0""")
def test_resizable_newlist(): alldescrs = ("<SizeDescr>, <FieldDescr length>," " <FieldDescr items>, <ArrayDescr>") builtin_test('newlist', [], VARLIST, """newlist $0, """+alldescrs+""" -> %r0""") builtin_test('newlist', [Constant(5, lltype.Signed)], VARLIST, """newlist $5, """+alldescrs+""" -> %r0""") builtin_test('newlist', [varoftype(lltype.Signed)], VARLIST, """newlist %i0, """+alldescrs+""" -> %r0""") builtin_test('newlist_clear', [Constant(5, lltype.Signed)], VARLIST, """newlist_clear $5, """+alldescrs+""" -> %r0""")
def test_graphs_from_direct_call(): cc = CallControl() F = lltype.FuncType([], lltype.Signed) f = lltype.functionptr(F, 'f', graph='fgraph') v = varoftype(lltype.Signed) op = SpaceOperation('direct_call', [Constant(f, lltype.Ptr(F))], v) # lst = cc.graphs_from(op, {}.__contains__) assert lst is None # residual call # lst = cc.graphs_from(op, {'fgraph': True}.__contains__) assert lst == ['fgraph'] # normal call
def test_casts(self): self.do_check('cast_int_to_longlong', EffectInfo.OS_LLONG_FROM_INT, [lltype.Signed], lltype.SignedLongLong) self.do_check('cast_uint_to_longlong', EffectInfo.OS_LLONG_FROM_UINT, [lltype.Unsigned], lltype.SignedLongLong) self.do_check('truncate_longlong_to_int', EffectInfo.OS_LLONG_TO_INT, [lltype.SignedLongLong], lltype.Signed) self.do_check('cast_float_to_longlong', EffectInfo.OS_LLONG_FROM_FLOAT, [lltype.Float], lltype.SignedLongLong) self.do_check('cast_float_to_ulonglong', EffectInfo.OS_LLONG_FROM_FLOAT, [lltype.Float], lltype.UnsignedLongLong) self.do_check('cast_longlong_to_float', EffectInfo.OS_LLONG_TO_FLOAT, [lltype.SignedLongLong], lltype.Float) self.do_check('cast_ulonglong_to_float', EffectInfo.OS_LLONG_U_TO_FLOAT, [lltype.UnsignedLongLong], lltype.Float) for T1 in [lltype.SignedLongLong, lltype.UnsignedLongLong]: for T2 in [lltype.Signed, lltype.Unsigned]: self.do_check('cast_primitive', EffectInfo.OS_LLONG_TO_INT, [T1], T2) self.do_check('force_cast', EffectInfo.OS_LLONG_TO_INT, [T1], T2) if T2 == lltype.Signed: expected = EffectInfo.OS_LLONG_FROM_INT else: expected = EffectInfo.OS_LLONG_FROM_UINT self.do_check('cast_primitive', expected, [T2], T1) self.do_check('force_cast', expected, [T2], T1) # for T1 in [lltype.SignedLongLong, lltype.UnsignedLongLong]: for T2 in [lltype.SignedLongLong, lltype.UnsignedLongLong]: vlist = [varoftype(T1)] v_result = varoftype(T2) op = SpaceOperation('force_cast', vlist, v_result) tr = Transformer(FakeCPU(), FakeBuiltinCallControl()) op1 = tr.rewrite_operation(op) assert op1 is None
def test_llong_neg(self): T = lltype.SignedLongLong v = varoftype(T) v_result = varoftype(T) op = SpaceOperation('llong_neg', [v], v_result) tr = Transformer(FakeCPU(), FakeBuiltinCallControl()) oplist = tr.rewrite_operation(op) assert len(oplist) == 2 assert oplist[0].opname == 'residual_call_irf_f' assert oplist[0].args[0].value == 'llong_from_int' assert list(oplist[0].args[1]) == [const(0)] assert list(oplist[0].args[2]) == [] assert list(oplist[0].args[3]) == [] assert oplist[0].args[4] == 'calldescr-84' v_x = oplist[0].result assert isinstance(v_x, Variable) assert oplist[1].opname == 'residual_call_irf_f' assert oplist[1].args[0].value == 'llong_sub' assert list(oplist[1].args[1]) == [] assert list(oplist[1].args[2]) == [] assert list(oplist[1].args[3]) == [v_x, v] assert oplist[1].args[4] == 'calldescr-71' assert oplist[1].result == v_result
def get_exc_reconstruction_block(self, typedesc): exceptblock = self.graph.exceptblock self.mallocv.fixup_except_block(exceptblock) TEXC = exceptblock.inputargs[0].concretetype TVAL = exceptblock.inputargs[1].concretetype # v_ignored_type = varoftype(TEXC) v_incoming_value = varoftype(TVAL) block = Block([v_ignored_type, v_incoming_value]) # c_EXCTYPE = Constant(typedesc.MALLOCTYPE, lltype.Void) v = varoftype(lltype.Ptr(typedesc.MALLOCTYPE)) c_flavor = Constant({'flavor': 'gc'}, lltype.Void) op = SpaceOperation('malloc', [c_EXCTYPE, c_flavor], v) block.operations.append(op) # for name, FIELDTYPE in typedesc.names_and_types: EXACTPTR = lltype.Ptr(typedesc.name2subtype[name]) c_name = Constant(name) c_name.concretetype = lltype.Void # v_in = varoftype(EXACTPTR) op = SpaceOperation('cast_pointer', [v_incoming_value], v_in) block.operations.append(op) # v_field = varoftype(FIELDTYPE) op = SpaceOperation('getfield', [v_in, c_name], v_field) block.operations.append(op) # v_out = varoftype(EXACTPTR) op = SpaceOperation('cast_pointer', [v], v_out) block.operations.append(op) # v0 = varoftype(lltype.Void) op = SpaceOperation('setfield', [v_out, c_name, v_field], v0) block.operations.append(op) # v_exc_value = varoftype(TVAL) op = SpaceOperation('cast_pointer', [v], v_exc_value) block.operations.append(op) # exc_type = self.mallocv.EXCTYPE_to_vtable[typedesc.MALLOCTYPE] c_exc_type = Constant(exc_type, TEXC) block.closeblock(Link([c_exc_type, v_exc_value], exceptblock)) return block
def test_fixed_setitem(): builtin_test('list.setitem/NONNEG', [ varoftype(FIXEDLIST), varoftype(lltype.Signed), varoftype(lltype.Void) ], lltype.Void, "") builtin_test('list.setitem/NEG', [ varoftype(FIXEDLIST), varoftype(lltype.Signed), varoftype(lltype.Void) ], lltype.Void, "")
def test_fixed_setitem(): builtin_test('list.setitem/NONNEG', [varoftype(FIXEDLIST), varoftype(lltype.Signed), varoftype(lltype.Signed)], lltype.Void, """ setarrayitem_gc_i %r0, %i0, %i1, <ArrayDescr> """) builtin_test('list.setitem/NEG', [varoftype(FIXEDLIST), varoftype(lltype.Signed), varoftype(lltype.Signed)], lltype.Void, """ -live- check_neg_index %r0, %i0, <ArrayDescr> -> %i1 setarrayitem_gc_i %r0, %i1, %i2, <ArrayDescr> """)