Author: Manuel Jacob
Branch: llvm-translation-backend
Changeset: r68802:e4ab9d710ba1
Date: 2014-01-21 11:50 +0100
http://bitbucket.org/pypy/pypy/changeset/e4ab9d710ba1/

Log:    Instead of marking every llexternal that calls a macro with a macro
        flag, we generate call wrappers for external functions by default. A
        call wrapper is a short C snippet that just calls the external
        function. This way we work on the API level instead of the ABI
        level, because the C compiler generates the actual code to call the
        external function. These functions are inlined because we use link-
        time optimization. One problem is currently that the call wrappers
        are not stripped from the binary.

diff --git a/pypy/module/_cffi_backend/misc.py 
b/pypy/module/_cffi_backend/misc.py
--- a/pypy/module/_cffi_backend/misc.py
+++ b/pypy/module/_cffi_backend/misc.py
@@ -238,7 +238,7 @@
 _is_nonnull_longdouble = rffi.llexternal(
     "pypy__is_nonnull_longdouble", [rffi.LONGDOUBLE], lltype.Bool,
     compilation_info=eci, _nowrapper=True, elidable_function=True,
-    sandboxsafe=True, macro=True)
+    sandboxsafe=True)
 
 # split here for JIT backends that don't support floats/longlongs/etc.
 def is_nonnull_longdouble(cdata):
diff --git a/rpython/jit/backend/x86/valgrind.py 
b/rpython/jit/backend/x86/valgrind.py
--- a/rpython/jit/backend/x86/valgrind.py
+++ b/rpython/jit/backend/x86/valgrind.py
@@ -21,8 +21,7 @@
         lltype.Void,
         compilation_info=eci,
         _nowrapper=True,
-        sandboxsafe=True,
-        macro=True)
+        sandboxsafe=True)
 
 # ____________________________________________________________
 
diff --git a/rpython/rlib/longlong2float.py b/rpython/rlib/longlong2float.py
--- a/rpython/rlib/longlong2float.py
+++ b/rpython/rlib/longlong2float.py
@@ -68,14 +68,12 @@
 uint2singlefloat = rffi.llexternal(
     "pypy__uint2singlefloat", [rffi.UINT], rffi.FLOAT,
     _callable=uint2singlefloat_emulator, compilation_info=eci,
-    _nowrapper=True, elidable_function=True, sandboxsafe=True,
-    llvm_wrapper=True)
+    _nowrapper=True, elidable_function=True, sandboxsafe=True)
 
 singlefloat2uint = rffi.llexternal(
     "pypy__singlefloat2uint", [rffi.FLOAT], rffi.UINT,
     _callable=singlefloat2uint_emulator, compilation_info=eci,
-    _nowrapper=True, elidable_function=True, sandboxsafe=True,
-    llvm_wrapper=True)
+    _nowrapper=True, elidable_function=True, sandboxsafe=True)
 
 
 class Float2LongLongEntry(ExtRegistryEntry):
diff --git a/rpython/rlib/rmd5.py b/rpython/rlib/rmd5.py
--- a/rpython/rlib/rmd5.py
+++ b/rpython/rlib/rmd5.py
@@ -51,7 +51,7 @@
     _rotateLeft = rffi.llexternal(
         "pypy__rotateLeft", [lltype.Unsigned, lltype.Signed], lltype.Unsigned,
         _callable=_rotateLeft_emulator, compilation_info=eci,
-        _nowrapper=True, elidable_function=True, llvm_wrapper=True)
+        _nowrapper=True, elidable_function=True)
     # we expect the function _rotateLeft to be actually inlined
 
 
diff --git a/rpython/rlib/rstack.py b/rpython/rlib/rstack.py
--- a/rpython/rlib/rstack.py
+++ b/rpython/rlib/rstack.py
@@ -20,15 +20,15 @@
         includes=['src/stack.h'],
         separate_module_files=[srcdir / 'stack.c', srcdir / 'threadlocal.c'])
 
-def llexternal(name, args, res, _callable=None, macro=None):
+def llexternal(name, args, res, _callable=None):
     return rffi.llexternal(name, args, res, compilation_info=compilation_info,
                            sandboxsafe=True, _nowrapper=True,
-                           _callable=_callable, macro=macro)
+                           _callable=_callable)
 
 _stack_get_end = llexternal('LL_stack_get_end', [], lltype.Signed,
-                            lambda: 0, True)
+                            lambda: 0)
 _stack_get_length = llexternal('LL_stack_get_length', [], lltype.Signed,
-                               lambda: 1, True)
+                               lambda: 1)
 _stack_set_length_fraction = llexternal('LL_stack_set_length_fraction',
                                         [lltype.Float], lltype.Void,
                                         lambda frac: None)
@@ -36,17 +36,15 @@
                                      [lltype.Signed], lltype.Char,
                                      lambda cur: '\x00')
 # the following is used by the JIT
-_stack_get_end_adr   = llexternal('LL_stack_get_end_adr',   [], lltype.Signed,
-                                  macro=True)
-_stack_get_length_adr= llexternal('LL_stack_get_length_adr',[], lltype.Signed,
-                                  macro=True)
+_stack_get_end_adr   = llexternal('LL_stack_get_end_adr',   [], lltype.Signed)
+_stack_get_length_adr= llexternal('LL_stack_get_length_adr',[], lltype.Signed)
 
 # the following is also used by the JIT: "critical code" paths are paths in
 # which we should not raise StackOverflow at all, but just ignore the stack 
limit
 _stack_criticalcode_start = llexternal('LL_stack_criticalcode_start', [],
-                                       lltype.Void, lambda: None, True)
+                                       lltype.Void, lambda: None)
 _stack_criticalcode_stop = llexternal('LL_stack_criticalcode_stop', [],
-                                      lltype.Void, lambda: None, True)
+                                      lltype.Void, lambda: None)
 
 def stack_check():
     if not we_are_translated():
diff --git a/rpython/rtyper/lltypesystem/llarena.py 
b/rpython/rtyper/lltypesystem/llarena.py
--- a/rpython/rtyper/lltypesystem/llarena.py
+++ b/rpython/rtyper/lltypesystem/llarena.py
@@ -602,7 +602,6 @@
                                                  lltype.Signed,
                                                  sandboxsafe=True,
                                                  _nowrapper=True,
-                                                 macro=True,
                                                  compilation_info=_eci)
 register_external(_round_up_for_allocation, [int, int], int,
                   'll_arena.round_up_for_allocation',
diff --git a/rpython/rtyper/lltypesystem/rffi.py 
b/rpython/rtyper/lltypesystem/rffi.py
--- a/rpython/rtyper/lltypesystem/rffi.py
+++ b/rpython/rtyper/lltypesystem/rffi.py
@@ -63,8 +63,7 @@
                sandboxsafe=False, releasegil='auto',
                _nowrapper=False, calling_conv='c',
                elidable_function=False, macro=None,
-               random_effects_on_gcobjs='auto',
-               llvm_wrapper=None):
+               random_effects_on_gcobjs='auto'):
     """Build an external function that will invoke the C function 'name'
     with the given 'args' types and 'result' type.
 
@@ -84,14 +83,9 @@
                 don't bother releasing the GIL.  An explicit True or False
                 overrides this logic.
     macro: whether to write a macro wrapper for this function. This is
-           necessary for calling macros in tests or when using the llvm
-           translation backend. Setting it to True generates a macro wrapper
-           named '_rpy_call_wrapper_{name}'. Setting it to a string
-           generates a macro wrapper named '_rpy_call_wrapper_{macro}'.
-    llvm_wrapper: same semantics as macro but for calling ordinary functions
-                  that the llvm translation backend can't handle, for example
-                  static functions defined in ExternalCompilationInfo's
-                  post_include_bits or functions with varargs.
+           necessary for calling macros in tests. Setting it to True generates
+           a macro wrapper named '_rpy_call_wrapper_{name}'. Setting it to a
+           string generates a macro wrapper named '_rpy_call_wrapper_{macro}'.
     """
     if _callable is not None:
         assert callable(_callable)
@@ -130,11 +124,6 @@
             invoke_around_handlers or   # because it can release the GIL
             has_callback)               # because the callback can do it
 
-    if llvm_wrapper is None:
-        llvm_wrapper = macro
-    if llvm_wrapper is not None:
-        kwds['llvm_wrapper'] = llvm_wrapper
-
     funcptr = lltype.functionptr(ext_type, name, external='C',
                                  compilation_info=compilation_info,
                                  _callable=_callable,
diff --git a/rpython/rtyper/lltypesystem/test/test_rffi.py 
b/rpython/rtyper/lltypesystem/test/test_rffi.py
--- a/rpython/rtyper/lltypesystem/test/test_rffi.py
+++ b/rpython/rtyper/lltypesystem/test/test_rffi.py
@@ -47,7 +47,7 @@
 
         eci = ExternalCompilationInfo(includes=['stuff.h'],
                                       include_dirs=[udir])
-        z = llexternal('X', [Signed], Signed, compilation_info=eci, macro=True)
+        z = llexternal('X', [Signed], Signed, compilation_info=eci)
 
         def f():
             return z(8)
@@ -298,7 +298,7 @@
 
         STUFFP = COpaquePtr(typedef='stuff_ptr', compilation_info=eci)
         ll_get = llexternal('get', [STUFFP], lltype.Signed,
-                            compilation_info=eci, llvm_wrapper=True)
+                            compilation_info=eci)
 
         def f():
             return ll_get(lltype.nullptr(STUFFP.TO))
diff --git a/rpython/rtyper/module/ll_os.py b/rpython/rtyper/module/ll_os.py
--- a/rpython/rtyper/module/ll_os.py
+++ b/rpython/rtyper/module/ll_os.py
@@ -22,7 +22,7 @@
 from rpython.rtyper.tool import rffi_platform as platform
 from rpython.rlib import rposix
 from rpython.translator.tool.cbuild import ExternalCompilationInfo
-from rpython.rtyper.lltypesystem.llmemory import itemoffsetof, offsetof, 
Address
+from rpython.rtyper.lltypesystem.llmemory import itemoffsetof, offsetof
 from rpython.rtyper.lltypesystem.rstr import STR
 from rpython.rlib.objectmodel import specialize
 
@@ -977,8 +977,7 @@
 
     @registering_if(os, 'makedev')
     def register_os_makedev(self):
-        c_makedev = self.llexternal('makedev', [rffi.INT, rffi.INT], rffi.INT,
-                                    macro=True)
+        c_makedev = self.llexternal('makedev', [rffi.INT, rffi.INT], rffi.INT)
         def makedev_llimpl(maj, min):
             return c_makedev(maj, min)
         return extdef([int, int], int,
@@ -986,7 +985,7 @@
 
     @registering_if(os, 'major')
     def register_os_major(self):
-        c_major = self.llexternal('major', [rffi.INT], rffi.INT, macro=True)
+        c_major = self.llexternal('major', [rffi.INT], rffi.INT)
         def major_llimpl(dev):
             return c_major(dev)
         return extdef([int], int,
@@ -994,7 +993,7 @@
 
     @registering_if(os, 'minor')
     def register_os_minor(self):
-        c_minor = self.llexternal('minor', [rffi.INT], rffi.INT, macro=True)
+        c_minor = self.llexternal('minor', [rffi.INT], rffi.INT)
         def minor_llimpl(dev):
             return c_minor(dev)
         return extdef([int], int,
@@ -1030,7 +1029,7 @@
     @registering(os.write)
     def register_os_write(self):
         os_write = self.llexternal(UNDERSCORE_ON_WIN32 + 'write',
-                                   [rffi.INT, Address, rffi.SIZE_T],
+                                   [rffi.INT, rffi.VOIDP, rffi.SIZE_T],
                                    rffi.SIZE_T)
 
         def os_write_llimpl(fd, data):
@@ -1040,8 +1039,7 @@
             try:
                 written = rffi.cast(lltype.Signed, os_write(
                     rffi.cast(rffi.INT, fd),
-                    rffi.cast(Address, buf),
-                    rffi.cast(rffi.SIZE_T, count)))
+                    buf, rffi.cast(rffi.SIZE_T, count)))
                 if written < 0:
                     raise OSError(rposix.get_errno(), "os_write failed")
             finally:
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
@@ -656,35 +656,18 @@
 
     def repr_ref(self, ptr_type, obj):
         if getattr(obj, 'external', None) == 'C':
-            if hasattr(obj, 'llvm_wrapper'):
+            if obj._name.startswith('llvm'):
+                name = '@' + obj._name
+            else:
                 wrapper_name, source = rffi._write_call_wrapper(
-                        obj._name, obj.llvm_wrapper, obj._TYPE)
+                        obj._name, database.unique_name(obj._name, False),
+                        obj._TYPE)
                 name = '@' + wrapper_name
                 database.genllvm.sources.append(source)
-            else:
-                name = '@' + obj._name
 
-            # Hack to support functions with different function signatures
-            prev_type = database.external_declared.get(name)
-            if prev_type is None:
-                database.external_declared[name] = self
-            elif prev_type is self:
-                ptr_type.refs[obj] = name
-                return
-            else:
-                ptr_type.refs[obj] = 'bitcast({}* {} to {}*)'.format(
-                        prev_type.repr_type(), name, self.repr_type())
-                return
             ptr_type.refs[obj] = name
-            if obj.calling_conv == 'c':
-                calling_conv = ''
-            elif obj.calling_conv == 'win':
-                # assume that x86_stdcallcc implies dllimport
-                calling_conv = 'dllimport x86_stdcallcc '
-            else:
-                raise NotImplementedError
-            database.f.write('declare {}{} {}({})\n'.format(
-                    calling_conv, self.result.repr_type(), name,
+            database.f.write('declare {} {}({})\n'.format(
+                    self.result.repr_type(), name,
                     ', '.join(arg.repr_type() for arg in self.args)))
             database.genllvm.ecis.append(obj.compilation_info)
         else:
@@ -740,7 +723,6 @@
         self.f = f
         self.names_counter = {}
         self.types = PRIMITIVES.copy()
-        self.external_declared = {}
         self.hashes = []
         self.stack_bottoms = []
 
@@ -764,14 +746,15 @@
                         .get_gc_fields_lltype() # hint for ll2ctypes
             return ret
 
-    def unique_name(self, name):
+    def unique_name(self, name, llvm_name=True):
         if name not in self.names_counter:
             self.names_counter[name] = 0
-            if self.identifier_regex.match(name) is None:
+            if llvm_name and self.identifier_regex.match(name) is None:
                 return '{}"{}"'.format(name[0], name[1:])
             return name
         self.names_counter[name] += 1
-        return self.unique_name('{}_{}'.format(name, self.names_counter[name]))
+        return self.unique_name('{}_{}'.format(name, self.names_counter[name]),
+                                llvm_name)
 
 
 OPS = {
@@ -1148,19 +1131,13 @@
             tmp.append('{arg.TV}'.format(arg=arg))
         args = ', '.join(tmp)
 
-        if (isinstance(fn, ConstantRepr) and
-            getattr(fn.value._obj, 'calling_conv', None) == 'win'):
-            calling_conv = 'x86_stdcallcc '
-        else:
-            calling_conv = ''
-
         if result.type_ is LLVMVoid:
-            fmt = 'call {calling_conv}void {fn.V}({args})'
+            fmt = 'call void {fn.V}({args})'
         elif (isinstance(result.type_, PtrType) and
               isinstance(result.type_.to, FuncType)):
-            fmt = '{result.V} = call {calling_conv}{fn.TV}({args})'
+            fmt = '{result.V} = call {fn.TV}({args})'
         else:
-            fmt = '{result.V} = call {calling_conv}{result.T} {fn.V}({args})'
+            fmt = '{result.V} = call {result.T} {fn.V}({args})'
         self.w(fmt.format(**locals()))
     op_indirect_call = op_direct_call
 
@@ -1764,15 +1741,14 @@
         exports.clear()
 
     def _compile(self, shared=False):
-        self.sources.append(py.code.Source(r'''
+        self.sources.append(str(py.code.Source(r'''
         void pypy_debug_catch_fatal_exception(void) {
             fprintf(stderr, "Fatal RPython error\n");
             abort();
-        }
-        '''))
+        }''')))
         eci = ExternalCompilationInfo(
             includes=['stdio.h', 'stdlib.h'],
-            separate_module_sources=self.sources,
+            separate_module_sources=['\n'.join(self.sources)],
             post_include_bits=['typedef _Bool bool_t;']
         ).merge(*self.ecis).convert_sources_to_files()
 
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to