Author: hager <[email protected]>
Branch: ppc-jit-backend
Changeset: r52353:e27ea20c9ee3
Date: 2012-02-10 15:36 +0100
http://bitbucket.org/pypy/pypy/changeset/e27ea20c9ee3/
Log: (bivab, hager): port regalloc tests from x86 backend
diff --git a/pypy/jit/backend/ppc/test/test_regalloc_2.py
b/pypy/jit/backend/ppc/test/test_regalloc_2.py
new file mode 100644
--- /dev/null
+++ b/pypy/jit/backend/ppc/test/test_regalloc_2.py
@@ -0,0 +1,702 @@
+
+""" Tests for register allocation for common constructs
+"""
+
+import py
+from pypy.jit.metainterp.history import BoxInt, ConstInt,\
+ BoxPtr, ConstPtr, BasicFailDescr, JitCellToken, TargetToken
+from pypy.jit.metainterp.resoperation import rop, ResOperation
+from pypy.jit.backend.llsupport.descr import GcCache
+from pypy.jit.backend.detect_cpu import getcpuclass
+from pypy.jit.backend.ppc.regalloc import Regalloc, PPCRegisterManager,\
+ PPCFrameManager
+from pypy.jit.backend.ppc.arch import IS_PPC_32, IS_PPC_64, MAX_REG_PARAMS
+from pypy.jit.tool.oparser import parse
+from pypy.rpython.lltypesystem import lltype, llmemory, rffi
+from pypy.rpython.annlowlevel import llhelper
+from pypy.rpython.lltypesystem import rclass, rstr
+from pypy.jit.codewriter import longlong
+from pypy.jit.codewriter.effectinfo import EffectInfo
+from pypy.jit.backend.llsupport.regalloc import is_comparison_or_ovf_op
+
+
+def test_is_comparison_or_ovf_op():
+ assert not is_comparison_or_ovf_op(rop.INT_ADD)
+ assert is_comparison_or_ovf_op(rop.INT_ADD_OVF)
+ assert is_comparison_or_ovf_op(rop.INT_EQ)
+
+CPU = getcpuclass()
+class MockGcDescr(GcCache):
+ def get_funcptr_for_new(self):
+ return 123
+ get_funcptr_for_newarray = get_funcptr_for_new
+ get_funcptr_for_newstr = get_funcptr_for_new
+ get_funcptr_for_newunicode = get_funcptr_for_new
+
+ def rewrite_assembler(self, cpu, operations):
+ pass
+
+class MockAssembler(object):
+ gcrefs = None
+ _float_constants = None
+
+ def __init__(self, cpu=None, gc_ll_descr=None):
+ self.movs = []
+ self.performs = []
+ self.lea = []
+ if cpu is None:
+ cpu = CPU(None, None)
+ cpu.setup_once()
+ self.cpu = cpu
+ if gc_ll_descr is None:
+ gc_ll_descr = MockGcDescr(False)
+ self.cpu.gc_ll_descr = gc_ll_descr
+
+ def dump(self, *args):
+ pass
+
+ def regalloc_mov(self, from_loc, to_loc):
+ self.movs.append((from_loc, to_loc))
+
+ def regalloc_perform(self, op, arglocs, resloc):
+ self.performs.append((op, arglocs, resloc))
+
+ def regalloc_perform_discard(self, op, arglocs):
+ self.performs.append((op, arglocs))
+
+ def load_effective_addr(self, *args):
+ self.lea.append(args)
+
+def fill_regs(regalloc, cls=BoxInt):
+ allboxes = []
+ for reg in PPCRegisterManager.all_regs:
+ box = cls()
+ allboxes.append(box)
+ regalloc.rm.try_allocate_reg()
+ return allboxes
+
+class RegAllocForTests(Regalloc):
+ position = 0
+ def _compute_next_usage(self, v, _):
+ return -1
+
+class BaseTestRegalloc(object):
+ cpu = CPU(None, None)
+ cpu.setup_once()
+
+ def supports_float(self):
+ return self.cpu.supports_floats
+
+ def raising_func(i):
+ if i:
+ raise LLException(zero_division_error,
+ zero_division_value)
+ FPTR = lltype.Ptr(lltype.FuncType([lltype.Signed], lltype.Void))
+ raising_fptr = llhelper(FPTR, raising_func)
+ zero_division_tp, zero_division_value = cpu.get_zero_division_error()
+ zd_addr = cpu.cast_int_to_adr(zero_division_tp)
+ zero_division_error = llmemory.cast_adr_to_ptr(zd_addr,
+ lltype.Ptr(rclass.OBJECT_VTABLE))
+ raising_calldescr = cpu.calldescrof(FPTR.TO, FPTR.TO.ARGS, FPTR.TO.RESULT,
+ EffectInfo.MOST_GENERAL)
+
+ targettoken = TargetToken()
+ targettoken2 = TargetToken()
+ fdescr1 = BasicFailDescr(1)
+ fdescr2 = BasicFailDescr(2)
+ fdescr3 = BasicFailDescr(3)
+
+ def setup_method(self, meth):
+ self.targettoken._ppc_loop_code = 0
+ self.targettoken2._ppc_loop_code = 0
+
+ def f1(x):
+ return x+1
+
+ def f2(x, y):
+ return x*y
+
+ def f10(*args):
+ assert len(args) == 10
+ return sum(args)
+
+ F1PTR = lltype.Ptr(lltype.FuncType([lltype.Signed], lltype.Signed))
+ F2PTR = lltype.Ptr(lltype.FuncType([lltype.Signed]*2, lltype.Signed))
+ F10PTR = lltype.Ptr(lltype.FuncType([lltype.Signed]*10, lltype.Signed))
+ f1ptr = llhelper(F1PTR, f1)
+ f2ptr = llhelper(F2PTR, f2)
+ f10ptr = llhelper(F10PTR, f10)
+
+ f1_calldescr = cpu.calldescrof(F1PTR.TO, F1PTR.TO.ARGS, F1PTR.TO.RESULT,
+ EffectInfo.MOST_GENERAL)
+ f2_calldescr = cpu.calldescrof(F2PTR.TO, F2PTR.TO.ARGS, F2PTR.TO.RESULT,
+ EffectInfo.MOST_GENERAL)
+ f10_calldescr= cpu.calldescrof(F10PTR.TO, F10PTR.TO.ARGS, F10PTR.TO.RESULT,
+ EffectInfo.MOST_GENERAL)
+
+ namespace = locals().copy()
+ type_system = 'lltype'
+
+ def parse(self, s, boxkinds=None):
+ return parse(s, self.cpu, self.namespace,
+ type_system=self.type_system,
+ boxkinds=boxkinds)
+
+ def interpret(self, ops, args, run=True):
+ loop = self.parse(ops)
+ looptoken = JitCellToken()
+ self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken)
+ arguments = []
+ for arg in args:
+ if isinstance(arg, int):
+ arguments.append(arg)
+ elif isinstance(arg, float):
+ arg = longlong.getfloatstorage(arg)
+ arguments.append(arg)
+ else:
+ assert isinstance(lltype.typeOf(arg), lltype.Ptr)
+ llgcref = lltype.cast_opaque_ptr(llmemory.GCREF, arg)
+ arguments.append(llgcref)
+ loop._jitcelltoken = looptoken
+ if run:
+ self.cpu.execute_token(looptoken, *arguments)
+ return loop
+
+ def prepare_loop(self, ops):
+ loop = self.parse(ops)
+ regalloc = Regalloc(assembler=self.cpu.asm,
+ frame_manager=PPCFrameManager())
+ regalloc.prepare_loop(loop.inputargs, loop.operations)
+ return regalloc
+
+ def getint(self, index):
+ return self.cpu.get_latest_value_int(index)
+
+ def getfloat(self, index):
+ return self.cpu.get_latest_value_float(index)
+
+ def getints(self, end):
+ return [self.cpu.get_latest_value_int(index) for
+ index in range(0, end)]
+
+ def getfloats(self, end):
+ return [longlong.getrealfloat(self.cpu.get_latest_value_float(index))
+ for index in range(0, end)]
+
+ def getptr(self, index, T):
+ gcref = self.cpu.get_latest_value_ref(index)
+ return lltype.cast_opaque_ptr(T, gcref)
+
+ def attach_bridge(self, ops, loop, guard_op_index, **kwds):
+ guard_op = loop.operations[guard_op_index]
+ assert guard_op.is_guard()
+ bridge = self.parse(ops, **kwds)
+ assert ([box.type for box in bridge.inputargs] ==
+ [box.type for box in guard_op.getfailargs()])
+ faildescr = guard_op.getdescr()
+ self.cpu.compile_bridge(faildescr, bridge.inputargs, bridge.operations,
+ loop._jitcelltoken)
+ return bridge
+
+ def run(self, loop, *arguments):
+ return self.cpu.execute_token(loop._jitcelltoken, *arguments)
+
+class TestRegallocSimple(BaseTestRegalloc):
+ def test_simple_loop(self):
+ ops = '''
+ [i0]
+ label(i0, descr=targettoken)
+ i1 = int_add(i0, 1)
+ i2 = int_lt(i1, 20)
+ guard_true(i2) [i1]
+ jump(i1, descr=targettoken)
+ '''
+ self.interpret(ops, [0])
+ assert self.getint(0) == 20
+
+ def test_two_loops_and_a_bridge(self):
+ ops = '''
+ [i0, i1, i2, i3]
+ label(i0, i1, i2, i3, descr=targettoken)
+ i4 = int_add(i0, 1)
+ i5 = int_lt(i4, 20)
+ guard_true(i5) [i4, i1, i2, i3]
+ jump(i4, i1, i2, i3, descr=targettoken)
+ '''
+ loop = self.interpret(ops, [0, 0, 0, 0])
+ ops2 = '''
+ [i5, i6, i7, i8]
+ label(i5, descr=targettoken2)
+ i1 = int_add(i5, 1)
+ i3 = int_add(i1, 1)
+ i4 = int_add(i3, 1)
+ i2 = int_lt(i4, 30)
+ guard_true(i2) [i4]
+ jump(i4, descr=targettoken2)
+ '''
+ loop2 = self.interpret(ops2, [0, 0, 0, 0])
+ bridge_ops = '''
+ [i4]
+ jump(i4, i4, i4, i4, descr=targettoken)
+ '''
+ bridge = self.attach_bridge(bridge_ops, loop2, 5)
+ self.run(loop2, 0, 0, 0, 0)
+ assert self.getint(0) == 31
+ assert self.getint(1) == 30
+ assert self.getint(2) == 30
+ assert self.getint(3) == 30
+
+ def test_pointer_arg(self):
+ ops = '''
+ [i0, p0]
+ label(i0, p0, descr=targettoken)
+ i1 = int_add(i0, 1)
+ i2 = int_lt(i1, 10)
+ guard_true(i2) [p0]
+ jump(i1, p0, descr=targettoken)
+ '''
+ S = lltype.GcStruct('S')
+ ptr = lltype.malloc(S)
+ self.cpu.clear_latest_values(2)
+ self.interpret(ops, [0, ptr])
+ assert self.getptr(0, lltype.Ptr(S)) == ptr
+
+ def test_exception_bridge_no_exception(self):
+ ops = '''
+ [i0]
+ i1 = same_as(1)
+ call(ConstClass(raising_fptr), i0, descr=raising_calldescr)
+ guard_exception(ConstClass(zero_division_error)) [i1]
+ finish(0)
+ '''
+ bridge_ops = '''
+ [i3]
+ i2 = same_as(2)
+ guard_no_exception() [i2]
+ finish(1)
+ '''
+ loop = self.interpret(ops, [0])
+ assert self.getint(0) == 1
+ bridge = self.attach_bridge(bridge_ops, loop, 2)
+ self.run(loop, 0)
+ assert self.getint(0) == 1
+
+ def test_inputarg_unused(self):
+ ops = '''
+ [i0]
+ finish(1)
+ '''
+ self.interpret(ops, [0])
+ # assert did not explode
+
+ def test_nested_guards(self):
+ ops = '''
+ [i0, i1]
+ guard_true(i0) [i0, i1]
+ finish(4)
+ '''
+ bridge_ops = '''
+ [i0, i1]
+ guard_true(i0) [i0, i1]
+ finish(3)
+ '''
+ loop = self.interpret(ops, [0, 10])
+ assert self.getint(0) == 0
+ assert self.getint(1) == 10
+ bridge = self.attach_bridge(bridge_ops, loop, 0)
+ self.run(loop, 0, 10)
+ assert self.getint(0) == 0
+ assert self.getint(1) == 10
+
+ def test_nested_unused_arg(self):
+ ops = '''
+ [i0, i1]
+ guard_true(i0) [i0, i1]
+ finish(1)
+ '''
+ loop = self.interpret(ops, [0, 1])
+ assert self.getint(0) == 0
+ bridge_ops = '''
+ [i0, i1]
+ finish(1, 2)
+ '''
+ self.attach_bridge(bridge_ops, loop, 0)
+ self.run(loop, 0, 1)
+
+ def test_spill_for_constant(self):
+ ops = '''
+ [i0, i1, i2, i3]
+ label(i0, i1, i2, i3, descr=targettoken)
+ i4 = int_add(3, i1)
+ i5 = int_lt(i4, 30)
+ guard_true(i5) [i0, i4, i2, i3]
+ jump(1, i4, 3, 4, descr=targettoken)
+ '''
+ self.interpret(ops, [0, 0, 0, 0])
+ assert self.getints(4) == [1, 30, 3, 4]
+
+ def test_spill_for_constant_lshift(self):
+ ops = '''
+ [i0, i2, i1, i3]
+ label(i0, i2, i1, i3, descr=targettoken)
+ i4 = int_lshift(1, i1)
+ i5 = int_add(1, i1)
+ i6 = int_lt(i5, 30)
+ guard_true(i6) [i4, i5, i2, i3]
+ jump(i4, 3, i5, 4, descr=targettoken)
+ '''
+ self.interpret(ops, [0, 0, 0, 0])
+ assert self.getints(4) == [1<<29, 30, 3, 4]
+ ops = '''
+ [i0, i1, i2, i3]
+ label(i0, i1, i2, i3, descr=targettoken)
+ i4 = int_lshift(1, i1)
+ i5 = int_add(1, i1)
+ i6 = int_lt(i5, 30)
+ guard_true(i6) [i4, i5, i2, i3]
+ jump(i4, i5, 3, 4, descr=targettoken)
+ '''
+ self.interpret(ops, [0, 0, 0, 0])
+ assert self.getints(4) == [1<<29, 30, 3, 4]
+ ops = '''
+ [i0, i3, i1, i2]
+ label(i0, i3, i1, i2, descr=targettoken)
+ i4 = int_lshift(1, i1)
+ i5 = int_add(1, i1)
+ i6 = int_lt(i5, 30)
+ guard_true(i6) [i4, i5, i2, i3]
+ jump(i4, 4, i5, 3, descr=targettoken)
+ '''
+ self.interpret(ops, [0, 0, 0, 0])
+ assert self.getints(4) == [1<<29, 30, 3, 4]
+
+ def test_result_selected_reg_via_neg(self):
+ ops = '''
+ [i0, i1, i2, i3]
+ label(i0, i1, i2, i3, descr=targettoken)
+ i6 = int_neg(i2)
+ i7 = int_add(1, i1)
+ i4 = int_lt(i7, 10)
+ guard_true(i4) [i0, i6, i7]
+ jump(1, i7, i2, i6, descr=targettoken)
+ '''
+ self.interpret(ops, [0, 0, 3, 0])
+ assert self.getints(3) == [1, -3, 10]
+
+ def test_compare_memory_result_survives(self):
+ ops = '''
+ [i0, i1, i2, i3]
+ label(i0, i1, i2, i3, descr=targettoken)
+ i4 = int_lt(i0, i1)
+ i5 = int_add(i3, 1)
+ i6 = int_lt(i5, 30)
+ guard_true(i6) [i4]
+ jump(i0, i1, i4, i5, descr=targettoken)
+ '''
+ self.interpret(ops, [0, 10, 0, 0])
+ assert self.getint(0) == 1
+
+ def test_jump_different_args(self):
+ ops = '''
+ [i0, i15, i16, i18, i1, i2, i3]
+ label(i0, i15, i16, i18, i1, i2, i3, descr=targettoken)
+ i4 = int_add(i3, 1)
+ i5 = int_lt(i4, 20)
+ guard_true(i5) [i2, i1]
+ jump(i0, i18, i15, i16, i2, i1, i4, descr=targettoken)
+ '''
+ self.interpret(ops, [0, 1, 2, 3, 0, 0, 0])
+
+ def test_op_result_unused(self):
+ ops = '''
+ [i0, i1]
+ i2 = int_add(i0, i1)
+ finish(0)
+ '''
+ self.interpret(ops, [0, 0])
+
+ def test_guard_value_two_boxes(self):
+ ops = '''
+ [i0, i1, i2, i3, i4, i5, i6, i7]
+ guard_value(i6, i1) [i0, i2, i3, i4, i5, i6]
+ finish(i0, i2, i3, i4, i5, i6)
+ '''
+ self.interpret(ops, [0, 0, 0, 0, 0, 0, 0, 0])
+ assert self.getint(0) == 0
+
+ def test_bug_wrong_stack_adj(self):
+ ops = '''
+ [i0, i1, i2, i3, i4, i5, i6, i7, i8]
+ i9 = same_as(0)
+ guard_true(i0) [i9, i0, i1, i2, i3, i4, i5, i6, i7, i8]
+ finish(1, i0, i1, i2, i3, i4, i5, i6, i7, i8)
+ '''
+ loop = self.interpret(ops, [0, 1, 2, 3, 4, 5, 6, 7, 8])
+ assert self.getint(0) == 0
+ bridge_ops = '''
+ [i9, i0, i1, i2, i3, i4, i5, i6, i7, i8]
+ call(ConstClass(raising_fptr), 0, descr=raising_calldescr)
+ finish(i0, i1, i2, i3, i4, i5, i6, i7, i8)
+ '''
+ self.attach_bridge(bridge_ops, loop, 1)
+ self.run(loop, 0, 1, 2, 3, 4, 5, 6, 7, 8)
+ assert self.getints(9) == range(9)
+
+ def test_loopargs(self):
+ ops = """
+ [i0, i1, i2, i3]
+ i4 = int_add(i0, i1)
+ jump(i4, i1, i2, i3)
+ """
+ regalloc = self.prepare_loop(ops)
+ assert len(regalloc.rm.reg_bindings) == 4
+ assert len(regalloc.frame_manager.bindings) == 0
+
+
+class TestRegallocCompOps(BaseTestRegalloc):
+
+ def test_cmp_op_0(self):
+ ops = '''
+ [i0, i3]
+ i1 = same_as(1)
+ i2 = int_lt(i0, 100)
+ guard_true(i3) [i1, i2]
+ finish(0, i2)
+ '''
+ self.interpret(ops, [0, 1])
+ assert self.getint(0) == 0
+
+class TestRegallocMoreRegisters(BaseTestRegalloc):
+
+ cpu = BaseTestRegalloc.cpu
+ targettoken = TargetToken()
+
+ S = lltype.GcStruct('S', ('field', lltype.Char))
+ fielddescr = cpu.fielddescrof(S, 'field')
+
+ A = lltype.GcArray(lltype.Char)
+ arraydescr = cpu.arraydescrof(A)
+
+ namespace = locals().copy()
+
+ def test_int_is_true(self):
+ ops = '''
+ [i0, i1, i2, i3, i4, i5, i6, i7]
+ i10 = int_is_true(i0)
+ i11 = int_is_true(i1)
+ i12 = int_is_true(i2)
+ i13 = int_is_true(i3)
+ i14 = int_is_true(i4)
+ i15 = int_is_true(i5)
+ i16 = int_is_true(i6)
+ i17 = int_is_true(i7)
+ finish(i10, i11, i12, i13, i14, i15, i16, i17)
+ '''
+ self.interpret(ops, [0, 42, 12, 0, 13, 0, 0, 3333])
+ assert self.getints(8) == [0, 1, 1, 0, 1, 0, 0, 1]
+
+ def test_comparison_ops(self):
+ ops = '''
+ [i0, i1, i2, i3, i4, i5, i6]
+ i10 = int_lt(i0, i1)
+ i11 = int_le(i2, i3)
+ i12 = int_ge(i4, i5)
+ i13 = int_eq(i5, i6)
+ i14 = int_gt(i6, i2)
+ i15 = int_ne(i2, i6)
+ finish(i10, i11, i12, i13, i14, i15)
+ '''
+ self.interpret(ops, [0, 1, 2, 3, 4, 5, 6])
+ assert self.getints(6) == [1, 1, 0, 0, 1, 1]
+
+ def test_strsetitem(self):
+ ops = '''
+ [p0, i]
+ strsetitem(p0, 1, i)
+ finish()
+ '''
+ llstr = rstr.mallocstr(10)
+ self.interpret(ops, [llstr, ord('a')])
+ assert llstr.chars[1] == 'a'
+
+ def test_setfield_char(self):
+ ops = '''
+ [p0, i]
+ setfield_gc(p0, i, descr=fielddescr)
+ finish()
+ '''
+ s = lltype.malloc(self.S)
+ self.interpret(ops, [s, ord('a')])
+ assert s.field == 'a'
+
+ def test_setarrayitem_gc(self):
+ ops = '''
+ [p0, i]
+ setarrayitem_gc(p0, 1, i, descr=arraydescr)
+ finish()
+ '''
+ s = lltype.malloc(self.A, 3)
+ self.interpret(ops, [s, ord('a')])
+ assert s[1] == 'a'
+
+ def test_division_optimized(self):
+ ops = '''
+ [i7, i6]
+ label(i7, i6, descr=targettoken)
+ i18 = int_floordiv(i7, i6)
+ i19 = int_xor(i7, i6)
+ i21 = int_lt(i19, 0)
+ i22 = int_mod(i7, i6)
+ i23 = int_is_true(i22)
+ i24 = int_eq(i6, 4)
+ guard_false(i24) [i18]
+ jump(i18, i6, descr=targettoken)
+ '''
+ self.interpret(ops, [10, 4])
+ assert self.getint(0) == 2
+ # FIXME: Verify that i19 - i23 are removed
+
+class TestRegallocFloats(BaseTestRegalloc):
+
+ def test_float_add(self):
+ if not self.supports_float():
+ py.test.skip("float not supported")
+ ops = '''
+ [f0, f1]
+ f2 = float_add(f0, f1)
+ finish(f2, f0, f1)
+ '''
+ self.interpret(ops, [3.0, 1.5])
+ assert self.getfloats(3) == [4.5, 3.0, 1.5]
+
+ def test_float_adds_stack(self):
+ if not self.supports_float():
+ py.test.skip("float not supported")
+ ops = '''
+ [f0, f1, f2, f3, f4, f5, f6, f7, f8]
+ f9 = float_add(f0, f1)
+ f10 = float_add(f8, 3.5)
+ finish(f9, f10, f2, f3, f4, f5, f6, f7, f8)
+ '''
+ self.interpret(ops, [0.1, .2, .3, .4, .5, .6, .7, .8, .9])
+ assert self.getfloats(9) == [.1+.2, .9+3.5, .3, .4, .5, .6, .7, .8, .9]
+
+ def test_lt_const(self):
+ if not self.supports_float():
+ py.test.skip("float not supported")
+ ops = '''
+ [f0]
+ i1 = float_lt(3.5, f0)
+ finish(i1)
+ '''
+ self.interpret(ops, [0.1])
+ assert self.getint(0) == 0
+
+ def test_bug_float_is_true_stack(self):
+ if not self.supports_float():
+ py.test.skip("float not supported")
+ # NB. float_is_true no longer exists. Unsure if keeping this test
+ # makes sense any more.
+ ops = '''
+ [f0, f1, f2, f3, f4, f5, f6, f7, f8, f9]
+ i0 = float_ne(f0, 0.0)
+ i1 = float_ne(f1, 0.0)
+ i2 = float_ne(f2, 0.0)
+ i3 = float_ne(f3, 0.0)
+ i4 = float_ne(f4, 0.0)
+ i5 = float_ne(f5, 0.0)
+ i6 = float_ne(f6, 0.0)
+ i7 = float_ne(f7, 0.0)
+ i8 = float_ne(f8, 0.0)
+ i9 = float_ne(f9, 0.0)
+ finish(i0, i1, i2, i3, i4, i5, i6, i7, i8, i9)
+ '''
+ loop = self.interpret(ops, [0.0, .1, .2, .3, .4, .5, .6, .7, .8, .9])
+ assert self.getints(9) == [0, 1, 1, 1, 1, 1, 1, 1, 1]
+
+class TestRegAllocCallAndStackDepth(BaseTestRegalloc):
+ def expected_param_depth(self, num_args):
+ # Assumes the arguments are all non-float
+ return max(num_args - MAX_REG_PARAMS, 0)
+
+ def test_one_call(self):
+ ops = '''
+ [i0, i1, i2, i3, i4, i5, i6, i7, i8, i9]
+ i10 = call(ConstClass(f1ptr), i0, descr=f1_calldescr)
+ finish(i10, i1, i2, i3, i4, i5, i6, i7, i8, i9)
+ '''
+ loop = self.interpret(ops, [4, 7, 9, 9 ,9, 9, 9, 9, 9, 9])
+ assert self.getints(10) == [5, 7, 9, 9, 9, 9, 9, 9, 9, 9]
+ clt = loop._jitcelltoken.compiled_loop_token
+ assert clt.param_depth == self.expected_param_depth(1)
+
+ def test_two_calls(self):
+ ops = '''
+ [i0, i1, i2, i3, i4, i5, i6, i7, i8, i9]
+ i10 = call(ConstClass(f1ptr), i0, descr=f1_calldescr)
+ i11 = call(ConstClass(f2ptr), i10, i1, descr=f2_calldescr)
+ finish(i11, i1, i2, i3, i4, i5, i6, i7, i8, i9)
+ '''
+ loop = self.interpret(ops, [4, 7, 9, 9 ,9, 9, 9, 9, 9, 9])
+ assert self.getints(10) == [5*7, 7, 9, 9, 9, 9, 9, 9, 9, 9]
+ clt = loop._jitcelltoken.compiled_loop_token
+ assert clt.param_depth == self.expected_param_depth(2)
+
+ def test_call_many_arguments(self):
+ # NB: The first and last arguments in the call are constants. This
+ # is primarily for x86-64, to ensure that loading a constant to an
+ # argument register or to the stack works correctly
+ ops = '''
+ [i0, i1, i2, i3, i4, i5, i6, i7]
+ i8 = call(ConstClass(f10ptr), 1, i0, i1, i2, i3, i4, i5, i6, i7, 10,
descr=f10_calldescr)
+ finish(i8)
+ '''
+ loop = self.interpret(ops, [2, 3, 4, 5, 6, 7, 8, 9])
+ assert self.getint(0) == 55
+ clt = loop._jitcelltoken.compiled_loop_token
+ assert clt.param_depth == self.expected_param_depth(10)
+
+ def test_bridge_calls_1(self):
+ ops = '''
+ [i0, i1]
+ i2 = call(ConstClass(f1ptr), i0, descr=f1_calldescr)
+ guard_value(i2, 0, descr=fdescr1) [i2, i1]
+ finish(i1)
+ '''
+ loop = self.interpret(ops, [4, 7])
+ assert self.getint(0) == 5
+ ops = '''
+ [i2, i1]
+ i3 = call(ConstClass(f2ptr), i2, i1, descr=f2_calldescr)
+ finish(i3, descr=fdescr2)
+ '''
+ bridge = self.attach_bridge(ops, loop, -2)
+
+ assert loop.operations[-2].getdescr()._ppc_bridge_param_depth\
+ == self.expected_param_depth(2)
+
+ self.run(loop, 4, 7)
+ assert self.getint(0) == 5*7
+
+ def test_bridge_calls_2(self):
+ ops = '''
+ [i0, i1]
+ i2 = call(ConstClass(f2ptr), i0, i1, descr=f2_calldescr)
+ guard_value(i2, 0, descr=fdescr1) [i2]
+ finish(i1)
+ '''
+ loop = self.interpret(ops, [4, 7])
+ assert self.getint(0) == 4*7
+ ops = '''
+ [i2]
+ i3 = call(ConstClass(f1ptr), i2, descr=f1_calldescr)
+ finish(i3, descr=fdescr2)
+ '''
+ bridge = self.attach_bridge(ops, loop, -2)
+
+ assert loop.operations[-2].getdescr()._ppc_bridge_param_depth\
+ == self.expected_param_depth(2)
+
+ self.run(loop, 4, 7)
+ assert self.getint(0) == 29
+
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit