Commits

David Schneider committed ca3a3a1

move x86/test_regalloc.py -> llsupport/test_regalloc_integration.py

Comments (0)

Files changed (2)

rpython/jit/backend/llsupport/test/test_regalloc_integration.py

+
+""" Tests for register allocation for common constructs
+"""
+
+import py
+from rpython.jit.metainterp.history import BoxInt, ConstInt,\
+     BoxPtr, ConstPtr, BasicFailDescr, JitCellToken, TargetToken
+from rpython.jit.metainterp.resoperation import rop, ResOperation
+from rpython.jit.backend.llsupport.descr import GcCache
+from rpython.jit.backend.detect_cpu import getcpuclass
+from rpython.jit.backend.llsupport.regalloc import is_comparison_or_ovf_op
+from rpython.jit.tool.oparser import parse
+from rpython.rtyper.lltypesystem import lltype, llmemory, rffi
+from rpython.rtyper.annlowlevel import llhelper
+from rpython.rtyper.lltypesystem import rclass, rstr
+from rpython.jit.codewriter import longlong
+from rpython.jit.codewriter.effectinfo import EffectInfo
+
+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)
+
+
+def get_zero_division_error(self):
+    # for tests, a random emulated ll_inst will do
+    ll_inst = lltype.malloc(rclass.OBJECT)
+    ll_inst.typeptr = lltype.malloc(rclass.OBJECT_VTABLE,
+                                    immortal=True)
+    _zer_error_vtable = llmemory.cast_ptr_to_adr(ll_inst.typeptr)
+    zer_vtable = self.cast_adr_to_int(_zer_error_vtable)
+    zer_inst = lltype.cast_opaque_ptr(llmemory.GCREF, ll_inst)
+    return zer_vtable, zer_inst
+
+
+CPU = getcpuclass()
+class BaseTestRegalloc(object):
+    cpu = CPU(None, None)
+    cpu.setup_once()
+
+    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 = get_zero_division_error(cpu)
+    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._ll_loop_code = 0
+        self.targettoken2._ll_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, namespace=None):
+        return parse(s, self.cpu, namespace or 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.deadframe = self.cpu.execute_token(looptoken, *arguments)
+        return loop
+
+    def prepare_loop(self, ops):
+        loop = self.parse(ops)
+        regalloc = self.cpu.build_regalloc()
+        regalloc.prepare_loop(loop.inputargs, loop.operations,
+                              loop.original_jitcell_token, [])
+        return regalloc
+
+    def getint(self, index):
+        return self.cpu.get_int_value(self.deadframe, index)
+
+    def getfloat(self, index):
+        return self.cpu.get_float_value(self.deadframe, index)
+
+    def getints(self, end):
+        return [self.cpu.get_int_value(self.deadframe, index) for
+                index in range(0, end)]
+
+    def getfloats(self, end):
+        return [longlong.getrealfloat(
+                    self.cpu.get_float_value(self.deadframe, index))
+                for index in range(0, end)]
+
+    def getptr(self, index, T):
+        gcref = self.cpu.get_ref_value(self.deadframe, 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):
+        self.deadframe = self.cpu.execute_token(loop._jitcelltoken, *arguments)
+        return self.cpu.get_latest_descr(self.deadframe)
+
+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.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(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)
+        '''
+        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)
+        '''
+        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)
+        guard_true(i9) [i0, i1, i2, i3, i4, i5, i6, i7, i8]
+        finish()
+        '''
+        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)
+        # we pass stuff on the frame
+        assert len(regalloc.rm.reg_bindings) == 0
+        assert len(regalloc.fm.bindings) == 4
+
+
+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]
+        i4 = int_neg(i2)
+        finish(0)
+        '''
+        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)
+        guard_true(i0) [i10, i11, i12, i13, i14, i15, i16, i17]
+        finish()
+        '''
+        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)
+        guard_true(i0) [i10, i11, i12, i13, i14, i15]
+        finish()
+        '''
+        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):
+        ops = '''
+        [f0, f1]
+        f2 = float_add(f0, f1)
+        i0 = same_as(0)
+        guard_true(i0) [f2, f0, f1]
+        finish()
+        '''
+        self.interpret(ops, [3.0, 1.5])
+        assert self.getfloats(3) == [4.5, 3.0, 1.5]
+
+    def test_float_adds_stack(self):
+        ops = '''
+        [f0, f1, f2, f3, f4, f5, f6, f7, f8]
+        f9 = float_add(f0, f1)
+        f10 = float_add(f8, 3.5)
+        i0 = same_as(0)
+        guard_true(i0) [f9, f10, f2, f3, f4, f5, f6, f7, f8]
+        finish()
+        '''
+        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):
+        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):
+        # 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)
+        guard_true(i0) [i0, i1, i2, i3, i4, i5, i6, i7, i8, i9]
+        finish()
+        '''
+        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 setup_class(cls):
+        py.test.skip("skip for now, not sure what do we do")
+    
+    def expected_frame_depth(self, num_call_args, num_pushed_input_args=0):
+        # Assumes the arguments are all non-float
+        if not self.cpu.IS_64_BIT:
+            extra_esp = num_call_args
+            return extra_esp
+        elif self.cpu.IS_64_BIT:
+            # 'num_pushed_input_args' is for X86_64 only
+            extra_esp = max(num_call_args - 6, 0)
+            return num_pushed_input_args + extra_esp
+
+    def test_one_call(self):
+        ops = '''
+        [i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i9b]
+        i10 = call(ConstClass(f1ptr), i0, descr=f1_calldescr)
+        guard_false(i10) [i10, i1, i2, i3, i4, i5, i6, i7, i8, i9, i9b]
+        '''
+        loop = self.interpret(ops, [4, 7, 9, 9 ,9, 9, 9, 9, 9, 9, 8])
+        assert self.getints(11) == [5, 7, 9, 9, 9, 9, 9, 9, 9, 9, 8]
+        clt = loop._jitcelltoken.compiled_loop_token
+        assert clt.frame_depth == self.expected_frame_depth(1, 5)
+
+    def test_one_call_reverse(self):
+        ops = '''
+        [i1, i2, i3, i4, i5, i6, i7, i8, i9, i9b, i0]
+        i10 = call(ConstClass(f1ptr), i0, descr=f1_calldescr)
+        guard_false(i10) [i10, i1, i2, i3, i4, i5, i6, i7, i8, i9, i9b]
+        '''
+        loop = self.interpret(ops, [7, 9, 9 ,9, 9, 9, 9, 9, 9, 8, 4])
+        assert self.getints(11) == [5, 7, 9, 9, 9, 9, 9, 9, 9, 9, 8]
+        clt = loop._jitcelltoken.compiled_loop_token
+        assert clt.frame_depth == self.expected_frame_depth(1, 6)
+
+    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)        
+        guard_false(i5) [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.frame_depth == self.expected_frame_depth(2, 5)
+
+    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.frame_depth == self.expected_frame_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, i0, i1]
+        guard_false(i1) [i1]
+        '''
+        loop = self.interpret(ops, [4, 7])
+        assert self.getint(0) == 5
+        clt = loop._jitcelltoken.compiled_loop_token
+        orgdepth = clt.frame_depth
+        assert orgdepth == self.expected_frame_depth(1, 2)
+
+        ops = '''
+        [i2, i0, i1]
+        i3 = call(ConstClass(f2ptr), i2, i1, descr=f2_calldescr)        
+        guard_false(i0, descr=fdescr2) [i3, i0]
+        '''
+        bridge = self.attach_bridge(ops, loop, -2)
+
+        assert clt.frame_depth == max(orgdepth, self.expected_frame_depth(2, 2))
+        assert loop.operations[-2].getdescr()._x86_bridge_frame_depth == \
+            self.expected_frame_depth(2, 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]
+        guard_false(i2) [i2]
+        '''
+        loop = self.interpret(ops, [4, 7])
+        assert self.getint(0) == 4*7
+        clt = loop._jitcelltoken.compiled_loop_token
+        orgdepth = clt.frame_depth
+        assert orgdepth == self.expected_frame_depth(2)
+
+        ops = '''
+        [i2]
+        i3 = call(ConstClass(f1ptr), i2, descr=f1_calldescr)        
+        guard_false(i3, descr=fdescr2) [i3]
+        '''
+        bridge = self.attach_bridge(ops, loop, -2)
+
+        assert clt.frame_depth == max(orgdepth, self.expected_frame_depth(1))
+        assert loop.operations[-2].getdescr()._x86_bridge_frame_depth == \
+            self.expected_frame_depth(1)
+
+        self.run(loop, 4, 7)
+        assert self.getint(0) == 29
+

rpython/jit/backend/x86/test/test_regalloc.py

-
-""" Tests for register allocation for common constructs
-"""
-
-import py
-from rpython.jit.metainterp.history import BoxInt, ConstInt,\
-     BoxPtr, ConstPtr, BasicFailDescr, JitCellToken, TargetToken
-from rpython.jit.metainterp.resoperation import rop, ResOperation
-from rpython.jit.backend.llsupport.descr import GcCache
-from rpython.jit.backend.detect_cpu import getcpuclass
-from rpython.jit.backend.llsupport.regalloc import is_comparison_or_ovf_op
-from rpython.jit.tool.oparser import parse
-from rpython.rtyper.lltypesystem import lltype, llmemory, rffi
-from rpython.rtyper.annlowlevel import llhelper
-from rpython.rtyper.lltypesystem import rclass, rstr
-from rpython.jit.codewriter import longlong
-from rpython.jit.codewriter.effectinfo import EffectInfo
-
-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)
-
-
-def get_zero_division_error(self):
-    # for tests, a random emulated ll_inst will do
-    ll_inst = lltype.malloc(rclass.OBJECT)
-    ll_inst.typeptr = lltype.malloc(rclass.OBJECT_VTABLE,
-                                    immortal=True)
-    _zer_error_vtable = llmemory.cast_ptr_to_adr(ll_inst.typeptr)
-    zer_vtable = self.cast_adr_to_int(_zer_error_vtable)
-    zer_inst = lltype.cast_opaque_ptr(llmemory.GCREF, ll_inst)
-    return zer_vtable, zer_inst
-
-
-CPU = getcpuclass()
-class BaseTestRegalloc(object):
-    cpu = CPU(None, None)
-    cpu.setup_once()
-
-    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 = get_zero_division_error(cpu)
-    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._ll_loop_code = 0
-        self.targettoken2._ll_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, namespace=None):
-        return parse(s, self.cpu, namespace or 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.deadframe = self.cpu.execute_token(looptoken, *arguments)
-        return loop
-
-    def prepare_loop(self, ops):
-        loop = self.parse(ops)
-        regalloc = self.cpu.build_regalloc()
-        regalloc.prepare_loop(loop.inputargs, loop.operations,
-                              loop.original_jitcell_token, [])
-        return regalloc
-
-    def getint(self, index):
-        return self.cpu.get_int_value(self.deadframe, index)
-
-    def getfloat(self, index):
-        return self.cpu.get_float_value(self.deadframe, index)
-
-    def getints(self, end):
-        return [self.cpu.get_int_value(self.deadframe, index) for
-                index in range(0, end)]
-
-    def getfloats(self, end):
-        return [longlong.getrealfloat(
-                    self.cpu.get_float_value(self.deadframe, index))
-                for index in range(0, end)]
-
-    def getptr(self, index, T):
-        gcref = self.cpu.get_ref_value(self.deadframe, 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):
-        self.deadframe = self.cpu.execute_token(loop._jitcelltoken, *arguments)
-        return self.cpu.get_latest_descr(self.deadframe)
-
-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.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(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)
-        '''
-        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)
-        '''
-        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)
-        guard_true(i9) [i0, i1, i2, i3, i4, i5, i6, i7, i8]
-        finish()
-        '''
-        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)
-        # we pass stuff on the frame
-        assert len(regalloc.rm.reg_bindings) == 0
-        assert len(regalloc.fm.bindings) == 4
-
-
-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]
-        i4 = int_neg(i2)
-        finish(0)
-        '''
-        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)
-        guard_true(i0) [i10, i11, i12, i13, i14, i15, i16, i17]
-        finish()
-        '''
-        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)
-        guard_true(i0) [i10, i11, i12, i13, i14, i15]
-        finish()
-        '''
-        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):
-        ops = '''
-        [f0, f1]
-        f2 = float_add(f0, f1)
-        i0 = same_as(0)
-        guard_true(i0) [f2, f0, f1]
-        finish()
-        '''
-        self.interpret(ops, [3.0, 1.5])
-        assert self.getfloats(3) == [4.5, 3.0, 1.5]
-
-    def test_float_adds_stack(self):
-        ops = '''
-        [f0, f1, f2, f3, f4, f5, f6, f7, f8]
-        f9 = float_add(f0, f1)
-        f10 = float_add(f8, 3.5)
-        i0 = same_as(0)
-        guard_true(i0) [f9, f10, f2, f3, f4, f5, f6, f7, f8]
-        finish()
-        '''
-        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):
-        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):
-        # 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)
-        guard_true(i0) [i0, i1, i2, i3, i4, i5, i6, i7, i8, i9]
-        finish()
-        '''
-        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 setup_class(cls):
-        py.test.skip("skip for now, not sure what do we do")
-    
-    def expected_frame_depth(self, num_call_args, num_pushed_input_args=0):
-        # Assumes the arguments are all non-float
-        if not self.cpu.IS_64_BIT:
-            extra_esp = num_call_args
-            return extra_esp
-        elif self.cpu.IS_64_BIT:
-            # 'num_pushed_input_args' is for X86_64 only
-            extra_esp = max(num_call_args - 6, 0)
-            return num_pushed_input_args + extra_esp
-
-    def test_one_call(self):
-        ops = '''
-        [i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i9b]
-        i10 = call(ConstClass(f1ptr), i0, descr=f1_calldescr)
-        guard_false(i10) [i10, i1, i2, i3, i4, i5, i6, i7, i8, i9, i9b]
-        '''
-        loop = self.interpret(ops, [4, 7, 9, 9 ,9, 9, 9, 9, 9, 9, 8])
-        assert self.getints(11) == [5, 7, 9, 9, 9, 9, 9, 9, 9, 9, 8]
-        clt = loop._jitcelltoken.compiled_loop_token
-        assert clt.frame_depth == self.expected_frame_depth(1, 5)
-
-    def test_one_call_reverse(self):
-        ops = '''
-        [i1, i2, i3, i4, i5, i6, i7, i8, i9, i9b, i0]
-        i10 = call(ConstClass(f1ptr), i0, descr=f1_calldescr)
-        guard_false(i10) [i10, i1, i2, i3, i4, i5, i6, i7, i8, i9, i9b]
-        '''
-        loop = self.interpret(ops, [7, 9, 9 ,9, 9, 9, 9, 9, 9, 8, 4])
-        assert self.getints(11) == [5, 7, 9, 9, 9, 9, 9, 9, 9, 9, 8]
-        clt = loop._jitcelltoken.compiled_loop_token
-        assert clt.frame_depth == self.expected_frame_depth(1, 6)
-
-    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)        
-        guard_false(i5) [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.frame_depth == self.expected_frame_depth(2, 5)
-
-    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.frame_depth == self.expected_frame_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, i0, i1]
-        guard_false(i1) [i1]
-        '''
-        loop = self.interpret(ops, [4, 7])
-        assert self.getint(0) == 5
-        clt = loop._jitcelltoken.compiled_loop_token
-        orgdepth = clt.frame_depth
-        assert orgdepth == self.expected_frame_depth(1, 2)
-
-        ops = '''
-        [i2, i0, i1]
-        i3 = call(ConstClass(f2ptr), i2, i1, descr=f2_calldescr)        
-        guard_false(i0, descr=fdescr2) [i3, i0]
-        '''
-        bridge = self.attach_bridge(ops, loop, -2)
-
-        assert clt.frame_depth == max(orgdepth, self.expected_frame_depth(2, 2))
-        assert loop.operations[-2].getdescr()._x86_bridge_frame_depth == \
-            self.expected_frame_depth(2, 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]
-        guard_false(i2) [i2]
-        '''
-        loop = self.interpret(ops, [4, 7])
-        assert self.getint(0) == 4*7
-        clt = loop._jitcelltoken.compiled_loop_token
-        orgdepth = clt.frame_depth
-        assert orgdepth == self.expected_frame_depth(2)
-
-        ops = '''
-        [i2]
-        i3 = call(ConstClass(f1ptr), i2, descr=f1_calldescr)        
-        guard_false(i3, descr=fdescr2) [i3]
-        '''
-        bridge = self.attach_bridge(ops, loop, -2)
-
-        assert clt.frame_depth == max(orgdepth, self.expected_frame_depth(1))
-        assert loop.operations[-2].getdescr()._x86_bridge_frame_depth == \
-            self.expected_frame_depth(1)
-
-        self.run(loop, 4, 7)
-        assert self.getint(0) == 29
-