[pypy-commit] pypy ec-threadlocal: in-progress: JIT backend support
arigo
noreply at buildbot.pypy.org
Mon Jun 23 10:34:55 CEST 2014
Author: Armin Rigo <arigo at tunes.org>
Branch: ec-threadlocal
Changeset: r72149:5c7a1c9731c5
Date: 2014-06-23 10:34 +0200
http://bitbucket.org/pypy/pypy/changeset/5c7a1c9731c5/
Log: in-progress: JIT backend support
diff --git a/rpython/jit/backend/llsupport/test/ztranslation_test.py b/rpython/jit/backend/llsupport/test/ztranslation_test.py
--- a/rpython/jit/backend/llsupport/test/ztranslation_test.py
+++ b/rpython/jit/backend/llsupport/test/ztranslation_test.py
@@ -4,6 +4,8 @@
from rpython.rlib.jit import PARAMETERS, dont_look_inside
from rpython.rlib.jit import promote
from rpython.rlib import jit_hooks
+from rpython.rlib.objectmodel import keepalive_until_here
+from rpython.rlib.rthread import ThreadLocalReference
from rpython.jit.backend.detect_cpu import getcpuclass
from rpython.jit.backend.test.support import CCompiledMixin
from rpython.jit.codewriter.policy import StopAtXPolicy
@@ -21,6 +23,7 @@
# - profiler
# - full optimizer
# - floats neg and abs
+ # - threadlocalref_get
class Frame(object):
_virtualizable_ = ['i']
@@ -28,6 +31,10 @@
def __init__(self, i):
self.i = i
+ class Foo(object):
+ pass
+ t = ThreadLocalReference(Foo)
+
@dont_look_inside
def myabs(x):
return abs(x)
@@ -56,6 +63,7 @@
k = myabs(j)
if k - abs(j): raise ValueError
if k - abs(-j): raise ValueError
+ if t.get().nine != 9: raise ValueError
return chr(total % 253)
#
from rpython.rtyper.lltypesystem import lltype, rffi
@@ -78,8 +86,12 @@
return res
#
def main(i, j):
+ foo = Foo()
+ foo.nine = -(i + j)
+ t.set(foo)
a_char = f(i, j)
a_float = libffi_stuff(i, j)
+ keepalive_until_here(foo)
return ord(a_char) * 10 + int(a_float)
expected = main(40, -49)
res = self.meta_interp(main, [40, -49])
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
@@ -2351,10 +2351,29 @@
assert isinstance(reg, RegLoc)
self.mc.MOV_rr(reg.value, ebp.value)
+ def threadlocalref_get(self, op, resloc):
+ # this function is only called on Linux
+ from rpython.jit.codewriter.jitcode import ThreadLocalRefDescr
+ from rpython.jit.backend.x86 import stmtlocal
+ assert isinstance(resloc, RegLoc)
+ effectinfo = op.getdescr().get_extra_info()
+ assert len(effectinfo.extradescrs) == 1
+ ed = effectinfo.extradescrs[0]
+ assert isinstance(ed, ThreadLocalRefDescr)
+ addr1 = rffi.cast(lltype.Signed, ed.get_tlref_addr())
+ addr0 = stmtlocal.threadlocal_base()
+ addr = addr1 - addr0
+ assert rx86.fits_in_32bits(addr)
+ mc = self.mc
+ mc.writechar(stmtlocal.SEGMENT_TL) # prefix
+ mc.MOV_rj(resloc.value, addr)
+
+
genop_discard_list = [Assembler386.not_implemented_op_discard] * rop._LAST
genop_list = [Assembler386.not_implemented_op] * rop._LAST
genop_llong_list = {}
genop_math_list = {}
+genop_tlref_list = {}
genop_guard_list = [Assembler386.not_implemented_op_guard] * rop._LAST
for name, value in Assembler386.__dict__.iteritems():
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
@@ -2,7 +2,7 @@
""" Register allocation scheme.
"""
-import os
+import os, sys
from rpython.jit.backend.llsupport import symbolic
from rpython.jit.backend.llsupport.descr import (ArrayDescr, CallDescr,
unpack_arraydescr, unpack_fielddescr, unpack_interiorfielddescr)
@@ -692,6 +692,15 @@
loc0 = self.xrm.force_result_in_reg(op.result, op.getarg(1))
self.perform_math(op, [loc0], loc0)
+ TLREF_SUPPORT = sys.platform.startswith('linux')
+
+ def _consider_threadlocalref_get(self, op):
+ if self.TLREF_SUPPORT:
+ resloc = self.force_allocate_reg(op.result)
+ self.assembler.threadlocalref_get(op, resloc)
+ else:
+ self._consider_call(op)
+
def _call(self, op, arglocs, force_store=[], guard_not_forced_op=None):
# we need to save registers on the stack:
#
@@ -769,6 +778,8 @@
return
if oopspecindex == EffectInfo.OS_MATH_SQRT:
return self._consider_math_sqrt(op)
+ if oopspecindex == EffectInfo.OS_THREADLOCALREF_GET:
+ return self._consider_threadlocalref_get(op)
self._consider_call(op)
def consider_call_may_force(self, op, guard_op):
diff --git a/rpython/jit/backend/x86/stmtlocal.py b/rpython/jit/backend/x86/stmtlocal.py
new file mode 100644
--- /dev/null
+++ b/rpython/jit/backend/x86/stmtlocal.py
@@ -0,0 +1,32 @@
+from rpython.rtyper.lltypesystem import lltype, rffi
+from rpython.translator.tool.cbuild import ExternalCompilationInfo
+from rpython.jit.backend.x86.arch import WORD
+
+SEGMENT_FS = '\x64'
+SEGMENT_GS = '\x65'
+
+if WORD == 4:
+ SEGMENT_TL = SEGMENT_GS
+ _instruction = "movl %%gs:0, %0"
+else:
+ SEGMENT_TL = SEGMENT_FS
+ _instruction = "movq %%fs:0, %0"
+
+eci = ExternalCompilationInfo(post_include_bits=['''
+#define RPY_STM_JIT 1
+static long pypy__threadlocal_base(void)
+{
+ /* XXX ONLY LINUX WITH GCC/CLANG FOR NOW XXX */
+ long result;
+ asm("%s" : "=r"(result));
+ return result;
+}
+''' % _instruction])
+
+
+threadlocal_base = rffi.llexternal(
+ 'pypy__threadlocal_base',
+ [], lltype.Signed,
+ compilation_info=eci,
+ _nowrapper=True,
+ ) #transactionsafe=True)
diff --git a/rpython/jit/codewriter/jitcode.py b/rpython/jit/codewriter/jitcode.py
--- a/rpython/jit/codewriter/jitcode.py
+++ b/rpython/jit/codewriter/jitcode.py
@@ -130,6 +130,8 @@
# variable from anywhere.
def __init__(self, opaque_id):
+ from rpython.rtyper.lltypesystem.lloperation import llop
+ from rpython.rtyper.lltypesystem import llmemory
def get_tlref_addr():
return llop.threadlocalref_getaddr(llmemory.Address, opaque_id)
self.get_tlref_addr = get_tlref_addr
diff --git a/rpython/jit/metainterp/test/test_threadlocal.py b/rpython/jit/metainterp/test/test_threadlocal.py
--- a/rpython/jit/metainterp/test/test_threadlocal.py
+++ b/rpython/jit/metainterp/test/test_threadlocal.py
@@ -4,7 +4,7 @@
from rpython.rlib.jit import dont_look_inside
-class TestThreadLocal(LLJitMixin):
+class ThreadLocalTest(object):
def test_threadlocalref_get(self):
class Foo:
@@ -24,3 +24,7 @@
res = self.interp_operations(f, [])
assert res == 42
+
+
+class TestLLtype(ThreadLocalTest, LLJitMixin):
+ pass
diff --git a/rpython/rtyper/lltypesystem/lloperation.py b/rpython/rtyper/lltypesystem/lloperation.py
--- a/rpython/rtyper/lltypesystem/lloperation.py
+++ b/rpython/rtyper/lltypesystem/lloperation.py
@@ -542,6 +542,7 @@
'check_and_clear_exc': LLOp(),
'threadlocalref_get': LLOp(sideeffects=False),
+ 'threadlocalref_getaddr': LLOp(sideeffects=False),
'threadlocalref_set': LLOp(),
# __________ debugging __________
diff --git a/rpython/translator/c/src/threadlocal.h b/rpython/translator/c/src/threadlocal.h
--- a/rpython/translator/c/src/threadlocal.h
+++ b/rpython/translator/c/src/threadlocal.h
@@ -28,6 +28,7 @@
#define RPyThreadStaticTLS_Create(tls) (void)0
#define RPyThreadStaticTLS_Get(tls) tls
#define RPyThreadStaticTLS_Set(tls, value) tls = value
+#define OP_THREADLOCALREF_GETADDR(tlref, ptr) ptr = tlref
#endif
More information about the pypy-commit
mailing list