[pypy-commit] pypy default: Move read_timestamp away from its own operation, and use a call with an

arigo noreply at buildbot.pypy.org
Sun Aug 31 16:56:26 CEST 2014


Author: Armin Rigo <arigo at tunes.org>
Branch: 
Changeset: r73232:08e92f52e390
Date: 2014-08-31 16:56 +0200
http://bitbucket.org/pypy/pypy/changeset/08e92f52e390/

Log:	Move read_timestamp away from its own operation, and use a call with
	an OS_xxx value instead. It is a bit simpler everywhere, and more
	importantly, it lets backends support this operation or not (in
	which case they are just assembled as CALLs).

diff --git a/rpython/jit/backend/arm/opassembler.py b/rpython/jit/backend/arm/opassembler.py
--- a/rpython/jit/backend/arm/opassembler.py
+++ b/rpython/jit/backend/arm/opassembler.py
@@ -1147,14 +1147,15 @@
     emit_op_convert_longlong_bytes_to_float = gen_emit_unary_float_op(
                                     'longlong_bytes_to_float', 'VMOV_cc')
 
-    def emit_op_read_timestamp(self, op, arglocs, regalloc, fcond):
-        assert 0, 'not supported'
+    """   disabled: missing an implementation that works in user mode
+    def ..._read_timestamp(...):
         tmp = arglocs[0]
         res = arglocs[1]
         self.mc.MRC(15, 0, tmp.value, 15, 12, 1)
         self.mc.MOV_ri(r.ip.value, 0)
         self.mc.VMOV_cr(res.value, tmp.value, r.ip.value)
         return fcond
+    """
 
     def emit_op_cast_float_to_singlefloat(self, op, arglocs, regalloc, fcond):
         arg, res = arglocs
diff --git a/rpython/jit/backend/arm/regalloc.py b/rpython/jit/backend/arm/regalloc.py
--- a/rpython/jit/backend/arm/regalloc.py
+++ b/rpython/jit/backend/arm/regalloc.py
@@ -561,6 +561,8 @@
                 args = self.prepare_op_math_sqrt(op, fcond)
                 self.perform_math(op, args, fcond)
                 return
+            #if oopspecindex == EffectInfo.OS_MATH_READ_TIMESTAMP:
+            #    ...
         return self._prepare_call(op)
 
     def _prepare_call(self, op, force_store=[], save_all_regs=False):
@@ -1293,10 +1295,10 @@
     prepare_op_convert_longlong_bytes_to_float = prepare_float_op(base=False,
                               name='prepare_op_convert_longlong_bytes_to_float')
 
-    def prepare_op_read_timestamp(self, op, fcond):
-        loc = self.get_scratch_reg(INT)
-        res = self.vfprm.force_allocate_reg(op.result)
-        return [loc, res]
+    #def prepare_op_read_timestamp(self, op, fcond):
+    #    loc = self.get_scratch_reg(INT)
+    #    res = self.vfprm.force_allocate_reg(op.result)
+    #    return [loc, res]
 
     def prepare_op_cast_float_to_singlefloat(self, op, fcond):
         loc1 = self.make_sure_var_in_reg(op.getarg(0))
diff --git a/rpython/jit/backend/arm/runner.py b/rpython/jit/backend/arm/runner.py
--- a/rpython/jit/backend/arm/runner.py
+++ b/rpython/jit/backend/arm/runner.py
@@ -20,8 +20,7 @@
     IS_64_BIT = False
 
     supports_floats = True
-    supports_longlong = False # XXX requires an implementation of
-                              # read_timestamp that works in user mode
+    supports_longlong = True
     supports_singlefloats = True
 
     from rpython.jit.backend.arm.arch import JITFRAME_FIXED_SIZE
diff --git a/rpython/jit/backend/arm/test/test_basic.py b/rpython/jit/backend/arm/test/test_basic.py
--- a/rpython/jit/backend/arm/test/test_basic.py
+++ b/rpython/jit/backend/arm/test/test_basic.py
@@ -41,10 +41,6 @@
                 continue
             locals()[k] = lambda self: py.test.skip('requires longlong support')
 
-    def test_read_timestamp(self):
-        py.test.skip("The JIT on ARM does not support read_timestamp")
-
-  
     if not CPU.supports_floats:
         for k in ('test_float', 'test_residual_external_call'):
             locals()[k] = lambda self: py.test.skip('requires float support')
diff --git a/rpython/jit/backend/llgraph/runner.py b/rpython/jit/backend/llgraph/runner.py
--- a/rpython/jit/backend/llgraph/runner.py
+++ b/rpython/jit/backend/llgraph/runner.py
@@ -15,7 +15,6 @@
 
 from rpython.rlib.clibffi import FFI_DEFAULT_ABI
 from rpython.rlib.rarithmetic import ovfcheck, r_uint, r_ulonglong
-from rpython.rlib.rtimer import read_timestamp
 
 class LLTrace(object):
     has_been_freed = False
@@ -649,9 +648,6 @@
         result_adr = llmemory.cast_ptr_to_adr(struct.typeptr)
         return heaptracker.adr2int(result_adr)
 
-    def bh_read_timestamp(self):
-        return read_timestamp()
-
     def bh_new_raw_buffer(self, size):
         return lltype.malloc(rffi.CCHARP.TO, size, flavor='raw')
 
diff --git a/rpython/jit/backend/test/runner_test.py b/rpython/jit/backend/test/runner_test.py
--- a/rpython/jit/backend/test/runner_test.py
+++ b/rpython/jit/backend/test/runner_test.py
@@ -21,6 +21,9 @@
 from rpython.jit.backend.llsupport import jitframe
 
 
+IS_32_BIT = sys.maxint < 2**32
+IS_64_BIT = sys.maxint > 2**32
+
 def boxfloat(x):
     return BoxFloat(longlong.getfloatstorage(x))
 
@@ -1792,8 +1795,8 @@
                                                c_nest, c_nest], 'void')
 
     def test_read_timestamp(self):
-        if not self.cpu.supports_longlong:
-            py.test.skip("longlong test")
+        if IS_32_BIT and not self.cpu.supports_longlong:
+            py.test.skip("read_timestamp returns a longlong")
         if sys.platform == 'win32':
             # windows quite often is very inexact (like the old Intel 8259 PIC),
             # so we stretch the time a little bit.
@@ -1809,16 +1812,29 @@
         else:
             def wait_a_bit():
                 pass
+
+        from rpython.jit.codewriter.effectinfo import EffectInfo
+        from rpython.rlib import rtimer
+
+        effectinfo = EffectInfo([], [], [], [], [], [],
+                                EffectInfo.EF_CANNOT_RAISE,
+                                EffectInfo.OS_MATH_READ_TIMESTAMP)
+        FPTR = self.Ptr(self.FuncType([], lltype.SignedLongLong))
+        func_ptr = llhelper(FPTR, rtimer.read_timestamp)
+        FUNC = deref(FPTR)
+        funcbox = self.get_funcbox(self.cpu, func_ptr)
+
+        calldescr = self.cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, effectinfo)
         if longlong.is_64_bit:
-            got1 = self.execute_operation(rop.READ_TIMESTAMP, [], 'int')
+            got1 = self.execute_operation(rop.CALL, [funcbox], 'int', calldescr)
             wait_a_bit()
-            got2 = self.execute_operation(rop.READ_TIMESTAMP, [], 'int')
+            got2 = self.execute_operation(rop.CALL, [funcbox], 'int', calldescr)
             res1 = got1.getint()
             res2 = got2.getint()
         else:
-            got1 = self.execute_operation(rop.READ_TIMESTAMP, [], 'float')
+            got1 = self.execute_operation(rop.CALL, [funcbox],'float',calldescr)
             wait_a_bit()
-            got2 = self.execute_operation(rop.READ_TIMESTAMP, [], 'float')
+            got2 = self.execute_operation(rop.CALL, [funcbox],'float',calldescr)
             res1 = got1.getlonglong()
             res2 = got2.getlonglong()
         assert res1 < res2 < res1 + 2**32
@@ -1941,7 +1957,7 @@
     def test_convert_float_bytes(self):
         if not self.cpu.supports_floats:
             py.test.skip("requires floats")
-        if not self.cpu.supports_longlong:
+        if IS_32_BIT and not self.cpu.supports_longlong:
             py.test.skip("longlong test")
         t = 'int' if longlong.is_64_bit else 'float'
         res = self.execute_operation(rop.CONVERT_FLOAT_BYTES_TO_LONGLONG,
@@ -2642,8 +2658,8 @@
             (types.double, 12.3475226, rffi.DOUBLE),
             (types.float,  r_singlefloat(-592.75), rffi.FLOAT),
             ]:
-            if sys.maxint < 2**32 and TP in (lltype.SignedLongLong,
-                                             lltype.UnsignedLongLong):
+            if IS_32_BIT and TP in (lltype.SignedLongLong,
+                                    lltype.UnsignedLongLong):
                 if not cpu.supports_longlong:
                     continue
             if TP == rffi.DOUBLE:
@@ -2722,7 +2738,7 @@
             (types.uint32, rffi.UINT),
             (types.sint32, rffi.INT),
             ]
-        if sys.maxint < 2**32 and cpu.supports_longlong:
+        if IS_32_BIT and cpu.supports_longlong:
             ALL_TYPES += [
                 (types.uint64, lltype.UnsignedLongLong),
                 (types.sint64, lltype.SignedLongLong),
@@ -3577,7 +3593,7 @@
                 "%r: got %r, expected %r" % (RESTYPE, res.value, expected))
 
     def test_supports_longlong(self):
-        if sys.maxint > 2147483647:
+        if IS_64_BIT:
             assert not self.cpu.supports_longlong, (
                 "supports_longlong should be False on 64-bit platforms")
 
diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py
--- a/rpython/jit/backend/x86/assembler.py
+++ b/rpython/jit/backend/x86/assembler.py
@@ -1567,7 +1567,7 @@
         else:
             assert 0, itemsize
 
-    def genop_read_timestamp(self, op, arglocs, resloc):
+    def genop_math_read_timestamp(self, op, arglocs, resloc):
         self.mc.RDTSC()
         if longlong.is_64_bit:
             self.mc.SHL_ri(edx.value, 32)
diff --git a/rpython/jit/backend/x86/regalloc.py b/rpython/jit/backend/x86/regalloc.py
--- a/rpython/jit/backend/x86/regalloc.py
+++ b/rpython/jit/backend/x86/regalloc.py
@@ -801,6 +801,8 @@
                 return self._consider_get_errno(op)
             if oopspecindex == EffectInfo.OS_SET_ERRNO:
                 return self._consider_set_errno(op)
+            if oopspecindex == EffectInfo.OS_MATH_READ_TIMESTAMP:
+                return self._consider_math_read_timestamp(op)
         self._consider_call(op)
 
     def consider_call_may_force(self, op, guard_op):
@@ -1206,7 +1208,7 @@
         else:
             raise AssertionError("bad unicode item size")
 
-    def consider_read_timestamp(self, op):
+    def _consider_math_read_timestamp(self, op):
         tmpbox_high = TempBox()
         self.rm.force_allocate_reg(tmpbox_high, selected_reg=eax)
         if longlong.is_64_bit:
@@ -1214,7 +1216,7 @@
             # result in rdx
             result_loc = self.rm.force_allocate_reg(op.result,
                                                     selected_reg=edx)
-            self.perform(op, [], result_loc)
+            self.perform_math(op, [], result_loc)
         else:
             # on 32-bit, use both eax and edx as temporary registers,
             # use a temporary xmm register, and returns the result in
@@ -1224,7 +1226,7 @@
             xmmtmpbox = TempBox()
             xmmtmploc = self.xrm.force_allocate_reg(xmmtmpbox)
             result_loc = self.xrm.force_allocate_reg(op.result)
-            self.perform(op, [xmmtmploc], result_loc)
+            self.perform_math(op, [xmmtmploc], result_loc)
             self.xrm.possibly_free_var(xmmtmpbox)
             self.rm.possibly_free_var(tmpbox_low)
         self.rm.possibly_free_var(tmpbox_high)
diff --git a/rpython/jit/codewriter/effectinfo.py b/rpython/jit/codewriter/effectinfo.py
--- a/rpython/jit/codewriter/effectinfo.py
+++ b/rpython/jit/codewriter/effectinfo.py
@@ -79,6 +79,7 @@
     OS_LLONG_U_TO_FLOAT         = 94
     #
     OS_MATH_SQRT                = 100
+    OS_MATH_READ_TIMESTAMP      = 101
     #
     OS_RAW_MALLOC_VARSIZE_CHAR  = 110
     OS_RAW_FREE                 = 111
diff --git a/rpython/jit/codewriter/jtransform.py b/rpython/jit/codewriter/jtransform.py
--- a/rpython/jit/codewriter/jtransform.py
+++ b/rpython/jit/codewriter/jtransform.py
@@ -1910,6 +1910,12 @@
         else:
             raise NotImplementedError(oopspec_name)
 
+    def rewrite_op_ll_read_timestamp(self, op):
+        op1 = self.prepare_builtin_call(op, "ll_read_timestamp", [])
+        return self.handle_residual_call(op1,
+            oopspecindex=EffectInfo.OS_MATH_READ_TIMESTAMP,
+            extraeffect=EffectInfo.EF_CANNOT_RAISE)
+
     def rewrite_op_jit_force_quasi_immutable(self, op):
         v_inst, c_fieldname = op.args
         descr1 = self.cpu.fielddescrof(v_inst.concretetype.TO,
diff --git a/rpython/jit/codewriter/support.py b/rpython/jit/codewriter/support.py
--- a/rpython/jit/codewriter/support.py
+++ b/rpython/jit/codewriter/support.py
@@ -289,6 +289,10 @@
     # (which is a residual call right now in the x86 backend)
     return llop.cast_float_to_uint(lltype.Unsigned, x)
 
+def _ll_0_ll_read_timestamp():
+    from rpython.rlib import rtimer
+    return rtimer.read_timestamp()
+
 
 # math support
 # ------------
diff --git a/rpython/jit/metainterp/blackhole.py b/rpython/jit/metainterp/blackhole.py
--- a/rpython/jit/metainterp/blackhole.py
+++ b/rpython/jit/metainterp/blackhole.py
@@ -7,7 +7,6 @@
 from rpython.rlib.debug import ll_assert, make_sure_not_resized
 from rpython.rlib.objectmodel import we_are_translated
 from rpython.rlib.rarithmetic import intmask, LONG_BIT, r_uint, ovfcheck
-from rpython.rlib.rtimer import read_timestamp
 from rpython.rlib.unroll import unrolling_iterable
 from rpython.rtyper.lltypesystem import lltype, llmemory, rclass, rffi
 from rpython.rtyper.lltypesystem.lloperation import llop
@@ -1382,10 +1381,6 @@
     def bhimpl_copyunicodecontent(cpu, src, dst, srcstart, dststart, length):
         cpu.bh_copyunicodecontent(src, dst, srcstart, dststart, length)
 
-    @arguments(returns=LONGLONG_TYPECODE)
-    def bhimpl_ll_read_timestamp():
-        return read_timestamp()
-
     def _libffi_save_result(self, cif_description, exchange_buffer, result):
         ARRAY = lltype.Ptr(rffi.CArray(lltype.typeOf(result)))
         cast_int_to_ptr = self.cpu.cast_int_to_ptr
diff --git a/rpython/jit/metainterp/executor.py b/rpython/jit/metainterp/executor.py
--- a/rpython/jit/metainterp/executor.py
+++ b/rpython/jit/metainterp/executor.py
@@ -3,7 +3,6 @@
 
 from rpython.rtyper.lltypesystem import lltype, rstr
 from rpython.rlib.rarithmetic import ovfcheck, r_longlong, is_valid_int
-from rpython.rlib.rtimer import read_timestamp
 from rpython.rlib.unroll import unrolling_iterable
 from rpython.jit.metainterp.history import BoxInt, BoxPtr, BoxFloat, check_descr
 from rpython.jit.metainterp.history import INT, REF, FLOAT, VOID, AbstractDescr
@@ -268,15 +267,6 @@
     length = lengthbox.getint()
     rstr.copy_unicode_contents(src, dst, srcstart, dststart, length)
 
-def do_read_timestamp(cpu, _):
-    x = read_timestamp()
-    if longlong.is_64_bit:
-        assert is_valid_int(x)            # 64-bit
-        return BoxInt(x)
-    else:
-        assert isinstance(x, r_longlong)  # 32-bit
-        return BoxFloat(x)
-
 def do_keepalive(cpu, _, x):
     pass
 
diff --git a/rpython/jit/metainterp/pyjitpl.py b/rpython/jit/metainterp/pyjitpl.py
--- a/rpython/jit/metainterp/pyjitpl.py
+++ b/rpython/jit/metainterp/pyjitpl.py
@@ -1232,10 +1232,6 @@
             metainterp.history.record(rop.VIRTUAL_REF_FINISH,
                                       [vrefbox, nullbox], None)
 
-    @arguments()
-    def opimpl_ll_read_timestamp(self):
-        return self.metainterp.execute_and_record(rop.READ_TIMESTAMP, None)
-
     @arguments("box", "box", "box")
     def _opimpl_libffi_save_result(self, box_cif_description,
                                    box_exchange_buffer, box_result):
diff --git a/rpython/jit/metainterp/resoperation.py b/rpython/jit/metainterp/resoperation.py
--- a/rpython/jit/metainterp/resoperation.py
+++ b/rpython/jit/metainterp/resoperation.py
@@ -489,7 +489,6 @@
     '_MALLOC_LAST',
     'FORCE_TOKEN/0',
     'VIRTUAL_REF/2',         # removed before it's passed to the backend
-    'READ_TIMESTAMP/0',
     'MARK_OPAQUE_PTR/1b',
     # this one has no *visible* side effect, since the virtualizable
     # must be forced, however we need to execute it anyway


More information about the pypy-commit mailing list