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_dict_setinteriorfield(): DICT = lltype.GcArray( lltype.Struct('ENTRY', ('v', lltype.Signed), ('k', lltype.Signed))) v = varoftype(lltype.Ptr(DICT)) i = varoftype(lltype.Signed) v_void = varoftype(lltype.Void) op = SpaceOperation('setinteriorfield', [v, i, Constant('v', lltype.Void), i], v_void) op1 = Transformer(FakeCPU()).rewrite_operation(op) assert op1.opname == 'setinteriorfield_gc_i' assert op1.args == [v, i, i, ('interiorfielddescr', DICT, 'v')] op = SpaceOperation('setinteriorfield', [v, i, Constant('v', lltype.Void), v_void], v_void) op1 = Transformer(FakeCPU()).rewrite_operation(op) assert not op1
def test_unicode_concat(): # test that the oopspec is present and correctly transformed PSTR = lltype.Ptr(rstr.UNICODE) FUNC = lltype.FuncType([PSTR, PSTR], PSTR) func = lltype.functionptr(FUNC, 'll_strconcat', _callable=rstr.LLHelpers.ll_strconcat) v1 = varoftype(PSTR) v2 = varoftype(PSTR) v3 = varoftype(PSTR) op = SpaceOperation('direct_call', [const(func), v1, v2], v3) cc = FakeBuiltinCallControl() tr = Transformer(FakeCPU(), cc) op1 = tr.rewrite_operation(op) assert op1.opname == 'residual_call_r_r' assert op1.args[0].value == func assert op1.args[1] == 'calldescr-%d' % effectinfo.EffectInfo.OS_UNI_CONCAT assert op1.args[2] == ListOfKind('ref', [v1, v2]) assert op1.result == v3 # # check the callinfo_for_oopspec got = cc.callinfocollection.seen[0] assert got[0] == effectinfo.EffectInfo.OS_UNI_CONCAT assert got[1] == op1.args[1] # the calldescr assert heaptracker.int2adr(got[2]) == llmemory.cast_ptr_to_adr(func)
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 oplist[0].args[1] == 'calldescr-84' assert list(oplist[0].args[2]) == [const(0)] assert list(oplist[0].args[3]) == [] assert list(oplist[0].args[4]) == [] 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 oplist[1].args[1] == 'calldescr-76' assert list(oplist[1].args[2]) == [] assert list(oplist[1].args[3]) == [] assert list(oplist[1].args[4]) == [v, v_x] assert oplist[1].result == v_result
def test_unknown_operation(): op = SpaceOperation('foobar', [], varoftype(lltype.Void)) tr = Transformer() try: tr.rewrite_operation(op) except Exception, e: assert 'foobar' in str(e)
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 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 op1.args[1] == 'calldescr-%d' % oopspecindex assert list( op1.args[2]) == [v for v in vlist if not is_llf(v.concretetype)] assert list(op1.args[3]) == [] assert list( op1.args[4]) == [v for v in vlist if is_llf(v.concretetype)] assert op1.result == v_result
def test_optimize_goto_if_not__incoming(): v1 = Variable() v1.concretetype = lltype.Bool block = Block([v1]) block.exitswitch = v1 block.exits = [FakeLink(False), FakeLink(True)] assert not Transformer().optimize_goto_if_not(block)
def indirect_residual_call_test(argtypes, restype, expectedkind): # an indirect call that is residual in all cases is very similar to # a residual direct call op = get_direct_call_op(argtypes, restype) op.opname = 'indirect_call' op.args[0] = varoftype(op.args[0].concretetype) op.args.append(Constant(['somegraph1', 'somegraph2'], lltype.Void)) tr = Transformer(FakeCPU(), FakeResidualIndirectCallControl()) tr.graph = 'someinitialgraph' oplist = tr.rewrite_operation(op) op0, op1 = oplist reskind = getkind(restype)[0] assert op0.opname == 'residual_call_%s_%s' % (expectedkind, reskind) assert op0.result == op.result assert op0.args[0] == op.args[0] assert op0.args[1] == 'calldescr' assert len(op0.args) == 2 + len(expectedkind) for sublist, kind1 in zip(op0.args[2:], expectedkind): assert sublist.kind.startswith(kind1) assert list(sublist) == [ v for v in op.args[1:] if getkind(v.concretetype) == sublist.kind ] for v in op.args[1:]: kind = getkind(v.concretetype) assert kind == 'void' or kind[0] in expectedkind assert op1.opname == '-live-' assert op1.args == []
def test_optimize_goto_if_not__unknownop(): v3 = Variable() v3.concretetype = lltype.Bool block = Block([]) block.operations = [SpaceOperation('foobar', [], v3)] block.exitswitch = v3 block.exits = [FakeLink(False), FakeLink(True)] assert not Transformer().optimize_goto_if_not(block)
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 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) raises(NotImplementedError, tr.rewrite_operation, op)
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_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_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_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_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_malloc_new(): S = lltype.GcStruct('S') v = varoftype(lltype.Ptr(S)) op = SpaceOperation( 'malloc', [Constant(S, lltype.Void), Constant({'flavor': 'gc'}, lltype.Void)], v) op1 = Transformer(FakeCPU()).rewrite_operation(op) assert op1.opname == 'new' assert op1.args == [('sizedescr', S)]
def test_raw_malloc_fixedsize(): S = lltype.Struct('dummy', ('x', lltype.Signed)) v = varoftype(lltype.Ptr(S)) flags = Constant({'flavor': 'raw', 'zero': True}, lltype.Void) op = SpaceOperation('malloc', [Constant(S, lltype.Void), flags], v) tr = Transformer(FakeCPU(), FakeResidualCallControl()) op0, op1 = tr.rewrite_operation(op) assert op0.opname == 'residual_call_r_i' assert op0.args[0].value == 'raw_malloc_fixedsize_zero' #pseudo-fn as a str assert op1.opname == '-live-' assert op1.args == []
def test_cast_opaque_ptr(): S = lltype.GcStruct("S", ("x", lltype.Signed)) v1 = varoftype(lltype.Ptr(S)) v2 = varoftype(lltype.Ptr(rclass.OBJECT)) op = SpaceOperation('cast_opaque_ptr', [v1], v2) tr = Transformer() [op1, op2] = tr.rewrite_operation(op) assert op1.opname == 'mark_opaque_ptr' assert op1.args == [v1] assert op1.result is None assert op2 is None
def test_getfield_typeptr(): v_parent = varoftype(rclass.OBJECTPTR) c_name = Constant('typeptr', lltype.Void) v_result = varoftype(rclass.OBJECT.typeptr) op = SpaceOperation('getfield', [v_parent, c_name], v_result) oplist = Transformer(FakeCPU()).rewrite_operation(op) op0, op1 = oplist assert op0.opname == '-live-' assert op0.args == [] assert op1.opname == 'guard_class' assert op1.args == [v_parent] assert op1.result == v_result
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_raw_malloc_zero(): S = rffi.CArray(lltype.Signed) v1 = varoftype(lltype.Signed) v = varoftype(lltype.Ptr(S)) flags = Constant({'flavor': 'raw', 'zero': True}, lltype.Void) op = SpaceOperation('malloc_varsize', [Constant(S, lltype.Void), flags, v1], v) tr = Transformer(FakeCPU(), FakeResidualCallControl()) op0, op1 = tr.rewrite_operation(op) assert op0.opname == 'residual_call_ir_i' assert op0.args[0].value == 'raw_malloc_varsize_zero' # pseudo-fn as a str assert op1.opname == '-live-' assert op1.args == []
def test_promote_1(): v1 = varoftype(lltype.Signed) v2 = varoftype(lltype.Signed) op = SpaceOperation('hint', [v1, Constant({'promote': True}, lltype.Void)], v2) oplist = Transformer().rewrite_operation(op) op0, op1, op2 = oplist assert op0.opname == '-live-' assert op0.args == [] assert op1.opname == 'int_guard_value' assert op1.args == [v1] assert op1.result is None assert op2 is None
def test_int_eq(): v1 = varoftype(lltype.Signed) v2 = varoftype(lltype.Signed) v3 = varoftype(lltype.Bool) c0 = const(0) # for opname, reducedname in [('int_eq', 'int_is_zero'), ('int_ne', 'int_is_true')]: op = SpaceOperation(opname, [v1, v2], v3) op1 = Transformer().rewrite_operation(op) assert op1.opname == opname 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]
def test_ptr_eq(): v1 = varoftype(lltype.Ptr(rstr.STR)) v2 = varoftype(lltype.Ptr(rstr.STR)) v3 = varoftype(lltype.Bool) c0 = const(lltype.nullptr(rstr.STR)) # for opname, reducedname in [('ptr_eq', 'ptr_iszero'), ('ptr_ne', 'ptr_nonzero')]: op = SpaceOperation(opname, [v1, v2], v3) op1 = Transformer().rewrite_operation(op) assert op1.opname == opname 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]
def test_str_promote(): PSTR = lltype.Ptr(rstr.STR) v1 = varoftype(PSTR) v2 = varoftype(PSTR) op = SpaceOperation( 'hint', [v1, Constant({'promote_string': True}, lltype.Void)], v2) tr = Transformer(FakeCPU(), FakeBuiltinCallControl()) op0, op1, _ = tr.rewrite_operation(op) assert op1.opname == 'str_guard_value' assert op1.args[0] == v1 assert op1.args[2] == 'calldescr' assert op1.result == v2 assert op0.opname == '-live-'
def test_rename_on_links(): v1 = Variable() v2 = Variable() v2.concretetype = llmemory.Address v3 = Variable() block = Block([v1]) block.operations = [SpaceOperation('cast_pointer', [v1], v2)] block2 = Block([v3]) block.closeblock(Link([v2], block2)) Transformer().optimize_block(block) assert block.inputargs == [v1] assert block.operations == [] assert block.exits[0].target is block2 assert block.exits[0].args == [v1]
def test_optimize_goto_if_not__ptr_iszero(): for opname in ['ptr_iszero', 'ptr_nonzero']: v1 = Variable() v3 = Variable() v3.concretetype = lltype.Bool block = Block([v1]) block.operations = [SpaceOperation(opname, [v1], v3)] block.exitswitch = v3 block.exits = exits = [FakeLink(False), FakeLink(True)] res = Transformer().optimize_goto_if_not(block) assert res == True assert block.operations == [] assert block.exitswitch == (opname, v1, '-live-before') assert block.exits == exits
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[2]) == [] assert list(op1.args[3]) == [] assert list(op1.args[4]) == vlist assert op1.result == v_result