def test_assemble_loop(): ssarepr = SSARepr("test") i0, i1 = Register('int', 0x16), Register('int', 0x17) ssarepr.insns = [ (Label('L1'), ), ('goto_if_not_int_gt', i0, Constant(4, lltype.Signed), TLabel('L2')), ('int_add', i1, i0, '->', i1), ('int_sub', i0, Constant(1, lltype.Signed), '->', i0), ('goto', TLabel('L1')), (Label('L2'), ), ('int_return', i1), ] assembler = Assembler() jitcode = assembler.assemble(ssarepr) assert jitcode.code == ("\x00\x16\x04\x10\x00" "\x01\x17\x16\x17" "\x02\x16\x01\x16" "\x03\x00\x00" "\x04\x17") assert assembler.insns == { 'goto_if_not_int_gt/icL': 0, 'int_add/ii>i': 1, 'int_sub/ic>i': 2, 'goto/L': 3, 'int_return/i': 4 }
def test_format_assembler_list(): ssarepr = SSARepr("test") i0, i1 = Register('int', 0), Register('int', 1) ssarepr.insns = [ ('foobar', ListOfKind('int', [i0, Constant(123, lltype.Signed), i1])), ] asm = format_assembler(ssarepr) expected = """ foobar I[%i0, $123, %i1] """ assert asm == str(py.code.Source(expected)).strip() + '\n'
def test_format_assembler_float(): ssarepr = SSARepr("test") i1, r2, f3 = Register('int', 1), Register('ref', 2), Register('float', 3) ssarepr.insns = [ ('foobar', i1, r2, f3), ] asm = format_assembler(ssarepr) expected = """ foobar %i1, %r2, %f3 """ assert asm == str(py.code.Source(expected)).strip() + '\n'
def test_assemble_list(): ssarepr = SSARepr("test") i0, i1 = Register('int', 0x16), Register('int', 0x17) ssarepr.insns = [ ('foobar', ListOfKind('int', [i0, i1, Constant(42, lltype.Signed)]), ListOfKind('ref', [])), ] assembler = Assembler() jitcode = assembler.assemble(ssarepr) assert jitcode.code == "\x00\x03\x16\x17\xFF\x00" assert assembler.insns == {'foobar/IR': 0} assert jitcode.constants_i == [42]
def test_format_assembler_simple(): ssarepr = SSARepr("test") i0, i1, i2 = Register('int', 0), Register('int', 1), Register('int', 2) ssarepr.insns = [ ('int_add', i0, i1, '->', i2), ('int_return', i2), ] asm = format_assembler(ssarepr) expected = """ int_add %i0, %i1 -> %i2 int_return %i2 """ assert asm == str(py.code.Source(expected)).strip() + '\n'
def test_assemble_simple(): ssarepr = SSARepr("test") i0, i1, i2 = Register('int', 0), Register('int', 1), Register('int', 2) ssarepr.insns = [ ('int_add', i0, i1, '->', i2), ('int_return', i2), ] assembler = Assembler() jitcode = assembler.assemble(ssarepr) assert jitcode.code == ("\x00\x00\x01\x02" "\x01\x02") assert assembler.insns == {'int_add/ii>i': 0, 'int_return/i': 1} assert jitcode.num_regs_i() == 3 assert jitcode.num_regs_r() == 0 assert jitcode.num_regs_f() == 0
def test_assemble_r_int(): # r_int is a strange type, which the jit should replace with int. # r_uint is also replaced with int. ssarepr = SSARepr("test") i0, i1, i2 = Register('int', 0), Register('int', 1), Register('int', 2) ssarepr.insns = [ ('uint_add', i0, Constant(r_uint(42424242), lltype.Unsigned), '->', i1), ('int_add', i0, Constant(r_int(42424243), lltype.Signed), '->', i2), ] assembler = Assembler() jitcode = assembler.assemble(ssarepr) assert jitcode.constants_i == [42424242, 42424243] assert map(type, jitcode.constants_i) == [int, int]
def test_num_regs(): assembler = Assembler() ssarepr = SSARepr("test") ssarepr.insns = [] jitcode = assembler.assemble(ssarepr) assert jitcode.num_regs_i() == 0 assert jitcode.num_regs_r() == 0 assert jitcode.num_regs_f() == 0 ssarepr = SSARepr("test") ssarepr.insns = [('foobar', Register('int', 51), Register('ref', 27), Register('int', 12))] jitcode = assembler.assemble(ssarepr) assert jitcode.num_regs_i() == 52 assert jitcode.num_regs_r() == 28 assert jitcode.num_regs_f() == 0
def test_liveness(): ssarepr = SSARepr("test") i0, i1, i2 = Register('int', 0), Register('int', 1), Register('int', 2) ssarepr.insns = [ ('int_add', i0, Constant(10, lltype.Signed), '->', i1), ('-live-', i0, i1), ('-live-', i1, i2), ('int_add', i0, Constant(3, lltype.Signed), '->', i2), ('-live-', i2), ] assembler = Assembler() jitcode = assembler.assemble(ssarepr) assert jitcode.code == ( "\x00\x00\x0A\x01" # ends at 4 "\x00\x00\x03\x02") # ends at 8 assert assembler.insns == {'int_add/ic>i': 0} for i in range(8): if i != 4: py.test.raises(MissingLiveness, jitcode._live_vars, i) assert jitcode._live_vars(4) == '%i0 %i1 %i2' assert jitcode._live_vars(8) == '%i2'
def test_liveness(): ssarepr = SSARepr("test") i0, i1, i2 = Register('int', 0), Register('int', 1), Register('int', 2) ssarepr.insns = [ ('int_add', i0, Constant(10, lltype.Signed), '->', i1), ('-live-', i0, i1, i2), ('int_add', i0, Constant(3, lltype.Signed), '->', i2), ('-live-', i2), ] assembler = Assembler() jitcode = assembler.assemble(ssarepr) assert jitcode.code == ( "\x00\x00\x0A\x01" # ends at 4 "\x01\x00\x00" "\x00\x00\x03\x02" # ends at 13 "\x01\x04\x00") assert assembler.insns == {'int_add/ic>i': 0, 'live/': 1} all_liveness = "".join(assembler.all_liveness) op_live = assembler.insns['live/'] with pytest.raises(MissingLiveness): jitcode._live_vars(0, all_liveness, op_live) assert jitcode._live_vars(4, all_liveness, op_live) == '%i0 %i1 %i2' assert jitcode._live_vars(11, all_liveness, op_live) == '%i2'
def test_format_assembler_loop(): ssarepr = SSARepr("test") i0, i1 = Register('int', 0), Register('int', 1) ssarepr.insns = [ (Label('L1'), ), ('goto_if_not_int_gt', i0, Constant(0, lltype.Signed), TLabel('L2')), ('int_add', i1, i0, '->', i1), ('int_sub', i0, Constant(1, lltype.Signed), '->', i0), ('goto', TLabel('L1')), (Label('L2'), ), ('int_return', i1), ] asm = format_assembler(ssarepr) expected = """ L1: goto_if_not_int_gt %i0, $0, L2 int_add %i1, %i0 -> %i1 int_sub %i0, $1 -> %i0 goto L1 L2: int_return %i1 """ assert asm == str(py.code.Source(expected)).strip() + '\n'
def unformat_arg(s): if s.endswith(','): s = s[:-1].rstrip() if s[0] == '%': try: return registers[s] except KeyError: num = int(s[2:]) if s[1] == 'i': reg = Register('int', num) elif s[1] == 'r': reg = Register('ref', num) elif s[1] == 'f': reg = Register('float', num) else: raise AssertionError("bad register type") registers[s] = reg return reg elif s[0] == '$': intvalue = int(s[1:]) return Constant(intvalue, lltype.Signed) elif s[0] == 'L': return TLabel(s) elif s[0] in 'IRF' and s[1] == '[' and s[-1] == ']': items = split_words(s[2:-1]) items = map(unformat_arg, items) return ListOfKind({'I': 'int', 'R': 'ref', 'F': 'float'}[s[0]], items) elif s.startswith('<SwitchDictDescr '): assert s.endswith('>') switchdict = SwitchDictDescr() switchdict._labels = [] items = split_words(s[len('<SwitchDictDescr '):-1]) for item in items: key, value = item.split(':') value = value.rstrip(',') switchdict._labels.append((int(key), TLabel(value))) return switchdict else: raise AssertionError("unsupported argument: %r" % (s,))
def test_assemble_float_consts(): ssarepr = SSARepr("test") ssarepr.insns = [ ('float_return', Register('float', 13)), ('float_return', Constant(18.0, lltype.Float)), ('float_return', Constant(-4.0, lltype.Float)), ('float_return', Constant(128.1, lltype.Float)), ] assembler = Assembler() jitcode = assembler.assemble(ssarepr) assert jitcode.code == ("\x00\x0D" "\x00\xFF" "\x00\xFE" "\x00\xFD") assert assembler.insns == {'float_return/f': 0} assert jitcode.constants_f == [ longlong.getfloatstorage(18.0), longlong.getfloatstorage(-4.0), longlong.getfloatstorage(128.1) ]
def test_assemble_consts(): ssarepr = SSARepr("test") ssarepr.insns = [ ('int_return', Register('int', 13)), ('int_return', Constant(18, lltype.Signed)), ('int_return', Constant(-4, lltype.Signed)), ('int_return', Constant(128, lltype.Signed)), ('int_return', Constant(-129, lltype.Signed)), ] assembler = Assembler() jitcode = assembler.assemble(ssarepr) assert jitcode.code == ( "\x00\x0D" "\x01\x12" # use int_return/c for one-byte consts "\x01\xFC" "\x00\xFF" # use int_return/i for larger consts "\x00\xFE") assert assembler.insns == {'int_return/i': 0, 'int_return/c': 1} assert jitcode.constants_i == [128, -129]
def test_repr(): assert repr(Register('int', 13)) == '%i13'