Author: Manuel Jacob <[email protected]>
Branch: llvm-translation-backend
Changeset: r75424:72d355b06d86
Date: 2015-01-18 14:49 +0100
http://bitbucket.org/pypy/pypy/changeset/72d355b06d86/

Log:    Fix or implement various things to make all tests pass and
        translation succeed.

diff --git a/rpython/memory/gctransform/refcounting.py 
b/rpython/memory/gctransform/refcounting.py
--- a/rpython/memory/gctransform/refcounting.py
+++ b/rpython/memory/gctransform/refcounting.py
@@ -285,3 +285,9 @@
                           resulttype=llmemory.Address)
         hop.genop("direct_call", [self.identityhash_ptr, v_adr],
                   resultvar=hop.spaceop.result)
+
+    def gct_zero_gc_pointers_inside(self, hop):
+        pass
+
+    def gct_zero_everything_inside(self, hop):
+        pass
diff --git a/rpython/translator/c/genc.py b/rpython/translator/c/genc.py
--- a/rpython/translator/c/genc.py
+++ b/rpython/translator/c/genc.py
@@ -723,6 +723,7 @@
         print >> f, '\t%s;' % cdecl(typename, field.fieldname)
     print >> f, '};'
     print >> f
+    return fields
 
 def gen_forwarddecl(f, database):
     print >> f, '/***********************************************************/'
diff --git a/rpython/translator/llvm/genllvm.py 
b/rpython/translator/llvm/genllvm.py
--- a/rpython/translator/llvm/genllvm.py
+++ b/rpython/translator/llvm/genllvm.py
@@ -193,11 +193,19 @@
             return 'or({T} sext({lp.TV} to {T}), {rest.TV})'.format(**locals())
         elif isinstance(value, CDefinedIntSymbolic):
             if value is malloc_zero_filled:
-                return '1'
+                gctransformer = database.genllvm.gcpolicy.gctransformer
+                return str(int(gctransformer.malloc_zero_filled))
             elif value is _we_are_jitted:
                 return '0'
             elif value is running_on_llinterp:
                 return '0'
+            elif value.expr.startswith('RPY_TLOFS_'):
+                fieldname = value.expr[10:]
+                idx = database.tls_struct.fldnames_wo_voids.index(fieldname)
+                return ('ptrtoint({}* getelementptr({}* null, i64 0, i32 {}) '
+                        'to {})'.format(
+                        database.tls_struct.fldtypes_wo_voids[idx].repr_type(),
+                        database.tls_struct.repr_type(), idx, SIGNED_TYPE))
         elif isinstance(value, llmemory.AddressAsInt):
             return 'ptrtoint({.TV} to {})'.format(get_repr(value.adr.ptr),
                                                   SIGNED_TYPE)
@@ -358,6 +366,8 @@
     if type not in PRIMITIVES:
         size_in_bytes, is_unsigned = rffi.size_and_sign(type)
         PRIMITIVES[type] = IntegralType(size_in_bytes * 8, is_unsigned)
+for key, value in PRIMITIVES.items():
+    value.lltype = key
 LLVMSigned = PRIMITIVES[lltype.Signed]
 SIGNED_TYPE = LLVMSigned.repr_type()
 LLVMHalfWord = PRIMITIVES[llgroup.HALFWORD]
@@ -753,6 +763,8 @@
         self.types = PRIMITIVES.copy()
         self.hashes = []
         self.stack_bottoms = []
+        self.tls_getters = set()
+        self.tls_addr_wrapper = False
 
     def get_type(self, type):
         try:
@@ -772,6 +784,7 @@
             if ret.needs_gc_header:
                 _llvm_needs_header[type] = database.genllvm.gcpolicy \
                         .get_gc_fields_lltype() # hint for ll2ctypes
+            ret.lltype = type
             return ret
 
     def unique_name(self, name, llvm_name=True):
@@ -1379,6 +1392,12 @@
         self.op_direct_call(result, get_repr(llvm_memset), ptr, null_char,
                             size, null_int, null_bool)
 
+    def op_raw_memset(self, result, ptr, val, size):
+        assert 0 <= val.value <= 255
+        self.op_direct_call(result, get_repr(llvm_memset), ptr,
+                            ConstantRepr(LLVMChar, chr(val.value)),
+                            size, null_int, null_bool)
+
     def op_raw_memcopy(self, result, src, dst, size):
         self.op_direct_call(result, get_repr(llvm_memcpy), dst, src, size,
                             null_int, null_bool)
@@ -1443,6 +1462,9 @@
         else:
             assert False, "No subop {}".format(subopnum.value)
 
+    def op_gc_thread_die(self, result):
+        self.op_direct_call(result, get_repr(rpy_tls_thread_die))
+
     def _ignore(self, *args):
         pass
     op_gc_stack_bottom = _ignore
@@ -1484,6 +1506,39 @@
     def op_convert_longlong_bytes_to_float(self, result, ll):
         self.w('{result.V} = bitcast {ll.TV} to {result.T}'.format(**locals()))
 
+    def op_threadlocalref_get(self, result, offset):
+        if isinstance(offset, ConstantRepr):
+            assert isinstance(offset.value, CDefinedIntSymbolic)
+            fieldname = offset.value.expr
+            assert fieldname.startswith('RPY_TLOFS_')
+            fieldname = fieldname[10:]
+            if fieldname not in database.tls_getters:
+                database.tls_getters.add(fieldname)
+                from rpython.translator.c.database import LowLevelDatabase
+                from rpython.translator.c.support import cdecl
+                db = LowLevelDatabase()
+                pattern = ("{}() {{ return RPY_THREADLOCALREF_GET({}); }}")
+                database.genllvm.sources.append(pattern.format(
+                        cdecl(db.gettype(result.type.lltype),
+                              '_rpy_tls_get_' + fieldname), fieldname))
+                database.f.write('declare {result.T} 
@_rpy_tls_get_{fieldname}()'
+                        .format(**locals()))
+            self.w('{result.V} = call {result.T} @_rpy_tls_get_{fieldname}()'
+                    .format(**locals()))
+        else:
+            tls_addr = self._tmp(LLVMAddress)
+            self.op_threadlocalref_addr(tls_addr)
+            self.op_raw_load(result, tls_addr, offset)
+
+    def op_threadlocalref_addr(self, result):
+        if not database.tls_addr_wrapper:
+            database.tls_addr_wrapper = True
+            wrapper_src = ('char *_rpy_tls_addr() '
+                           '{ char *r; OP_THREADLOCALREF_ADDR(r); return r; }')
+            database.genllvm.sources.append(wrapper_src)
+            database.f.write('declare i8* @_rpy_tls_addr()\n')
+        self.w('{result.V} = call i8* @_rpy_tls_addr()'.format(**locals()))
+
 
 class GCPolicy(object):
     def __init__(self, genllvm):
@@ -1662,6 +1717,10 @@
                             eci)
 llvm_readcyclecounter = extfunc('llvm.readcyclecounter', [],
                                 lltype.SignedLongLong, eci)
+rpy_tls_program_init = extfunc('RPython_ThreadLocals_ProgramInit', [],
+                               lltype.Void, eci)
+rpy_tls_thread_die = extfunc('RPython_ThreadLocals_ThreadDie', [], lltype.Void,
+                             eci)
 del eci
 
 null_int = ConstantRepr(LLVMInt, 0)
@@ -1699,10 +1758,14 @@
 
     def prepare(self, entrypoint, secondary_entrypoints):
         if callable(entrypoint):
+            bk = self.translator.annotator.bookkeeper
+            has_tls = bool(bk.thread_local_fields)
             setup_ptr = self.gcpolicy.get_setup_ptr()
             def main(argc, argv):
                 llop.gc_stack_bottom(lltype.Void)
                 try:
+                    if has_tls:
+                        rpy_tls_program_init()
                     if setup_ptr is not None:
                         setup_ptr()
                     args = [rffi.charp2str(argv[i]) for i in range(argc)]
@@ -1733,6 +1796,11 @@
         self.ovf_err = self.exctransformer.get_builtin_exception(OverflowError)
         ovf_err_inst = self.ovf_err[1]
         self.gcpolicy._consider_constant(ovf_err_inst._T, ovf_err_inst._obj)
+
+        # XXX for some reason, this is needed to make all tests pass
+        tmp = self.exctransformer.get_builtin_exception(OSError)[1]
+        self.gcpolicy._consider_constant(tmp._T, tmp._obj)
+
         self.gcpolicy.finish()
 
     def _write_special_declarations(self, f):
@@ -1769,8 +1837,19 @@
                     f.write(line)
 
             database = Database(self, f)
+
+            from rpython.translator.c.database import LowLevelDatabase
+            from rpython.translator.c.genc import gen_threadlocal_structdef
+            db = LowLevelDatabase(self.translator)
+            with self.work_dir.join('structdef.h').open('w') as f2:
+                tls_fields = gen_threadlocal_structdef(f2, db)
+            database.tls_struct = StructType()
+            database.tls_struct.setup(
+                    'tls', [(LLVMInt, 'ready'), (LLVMAddress, 'stack_end')] +
+                           [(database.get_type(fld.FIELDTYPE), fld.fieldname)
+                            for fld in tls_fields], False)
+
             self._write_special_declarations(f)
-
             for export in self.entrypoints:
                 get_repr(export._as_ptr()).V
 
@@ -1803,8 +1882,13 @@
             raise Exception("RPYTHON_LLVM_ASSEMBLY must be 'false' or 'true'.")
 
         # merge ECIs
+        c_dir = local(cdir)
         eci = ExternalCompilationInfo(
-            includes=['stdio.h', 'stdlib.h'],
+            include_dirs=[cdir, c_dir / '..' / 'llvm', self.work_dir],
+            includes=['stdio.h', 'stdlib.h', 'src/threadlocal.h',
+                      'src/stack.h', 'structdef.h'],
+            separate_module_files=[c_dir / 'src' / 'threadlocal.c',
+                                   c_dir / 'src' / 'stack.c'],
             separate_module_sources=['\n'.join(self.sources)],
             post_include_bits=['typedef _Bool bool_t;']
         ).merge(*self.ecis).convert_sources_to_files()
diff --git a/rpython/translator/llvm/test/test_genllvm.py 
b/rpython/translator/llvm/test/test_genllvm.py
--- a/rpython/translator/llvm/test/test_genllvm.py
+++ b/rpython/translator/llvm/test/test_genllvm.py
@@ -287,7 +287,7 @@
         self.rpyexc_clear()
         ret = self.entry_point(*args)
         if self.rpyexc_occured():
-            name = ''.join(self.rpyexc_fetch_type().name._obj.items[:-1])
+            name = ''.join(self.rpyexc_fetch_type().name.chars)
             if expected_exception_name is not None:
                 assert name == expected_exception_name
                 return
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to