Author: Ronan Lamy <ronan.l...@gmail.com>
Branch: online-transforms
Changeset: r74414:0ba2b288f039
Date: 2014-11-09 00:22 +0000
http://bitbucket.org/pypy/pypy/changeset/0ba2b288f039/

Log:    hg merge default

diff --git a/pypy/module/cpyext/include/modsupport.h 
b/pypy/module/cpyext/include/modsupport.h
--- a/pypy/module/cpyext/include/modsupport.h
+++ b/pypy/module/cpyext/include/modsupport.h
@@ -78,11 +78,20 @@
 /*
  * This is from pyport.h.  Perhaps it belongs elsewhere.
  */
+#ifdef _WIN32
+/* explicitly export since PyAPI_FUNC is usually dllimport */
+#ifdef __cplusplus
+#define PyMODINIT_FUNC extern "C" __declspec(dllexport) void
+#else
+#define PyMODINIT_FUNC __declspec(dllexport) void
+#endif
+#else
 #ifdef __cplusplus
 #define PyMODINIT_FUNC extern "C" PyAPI_FUNC(void)
 #else
 #define PyMODINIT_FUNC PyAPI_FUNC(void)
 #endif
+#endif /* WIN32 */
 
 PyAPI_DATA(char *) _Py_PackageContext;
 
diff --git a/pypy/module/rctime/interp_time.py 
b/pypy/module/rctime/interp_time.py
--- a/pypy/module/rctime/interp_time.py
+++ b/pypy/module/rctime/interp_time.py
@@ -178,19 +178,19 @@
 if _WIN:
     win_eci = ExternalCompilationInfo(
         includes = ["time.h"],
-        post_include_bits = ["RPY_EXPORTED_FOR_TESTS\n"
+        post_include_bits = ["RPY_EXPORTED_FOR_TESTS "
                              "long pypy_get_timezone();\n"
-                             "RPY_EXPORTED_FOR_TESTS\n"
+                             "RPY_EXPORTED_FOR_TESTS "
                              "int pypy_get_daylight();\n"
-                             "RPY_EXPORTED_FOR_TESTS\n"
+                             "RPY_EXPORTED_FOR_TESTS "
                              "char** pypy_get_tzname();\n"
-                             "RPY_EXPORTED_FOR_TESTS\n"
-                             "void* pypy__tzset();"],
+                             "RPY_EXPORTED_FOR_TESTS "
+                             "void pypy__tzset();"],
         separate_module_sources = ["""
         long pypy_get_timezone() { return timezone; }
         int pypy_get_daylight() { return daylight; }
         char** pypy_get_tzname() { return tzname; }
-        void pypy__tzset() { return _tzset(); }
+        void pypy__tzset() { _tzset(); }
         """])
     # Ensure sure that we use _tzset() and timezone from the same C Runtime.
     c_tzset = external('pypy__tzset', [], lltype.Void, win_eci)
diff --git a/pypy/module/test_lib_pypy/ctypes_tests/_ctypes_test.c 
b/pypy/module/test_lib_pypy/ctypes_tests/_ctypes_test.c
--- a/pypy/module/test_lib_pypy/ctypes_tests/_ctypes_test.c
+++ b/pypy/module/test_lib_pypy/ctypes_tests/_ctypes_test.c
@@ -1,10 +1,10 @@
-#include "src/precommondefs.h"
-
 #if defined(_MSC_VER) || defined(__CYGWIN__)
 #include <windows.h>
 #define MS_WIN32
 #endif
 
+#include "src/precommondefs.h"
+
 #define EXPORT(x)  RPY_EXPORTED x
 
 #include <stdlib.h>
diff --git a/rpython/jit/metainterp/optimizeopt/rewrite.py 
b/rpython/jit/metainterp/optimizeopt/rewrite.py
--- a/rpython/jit/metainterp/optimizeopt/rewrite.py
+++ b/rpython/jit/metainterp/optimizeopt/rewrite.py
@@ -1,7 +1,8 @@
 from rpython.jit.codewriter.effectinfo import EffectInfo
+from rpython.jit.codewriter import longlong
 from rpython.jit.metainterp import compile
 from rpython.jit.metainterp.history import (Const, ConstInt, BoxInt, BoxFloat,
-    BoxPtr, make_hashable_int)
+    BoxPtr, make_hashable_int, ConstFloat)
 from rpython.jit.metainterp.optimize import InvalidLoop
 from rpython.jit.metainterp.optimizeopt.intutils import IntBound
 from rpython.jit.metainterp.optimizeopt.optimizer import (Optimization, 
REMOVED,
@@ -10,7 +11,7 @@
 from rpython.jit.metainterp.resoperation import (opboolinvers, opboolreflex, 
rop,
     ResOperation)
 from rpython.rlib.rarithmetic import highest_bit
-
+import math
 
 class OptRewrite(Optimization):
     """Rewrite operations into equivalent, cheaper operations.
@@ -231,6 +232,25 @@
         self.emit_operation(op)
         self.pure(rop.FLOAT_MUL, [arg2, arg1], op.result)
 
+    def optimize_FLOAT_TRUEDIV(self, op):
+        arg1 = op.getarg(0)
+        arg2 = op.getarg(1)
+        v2 = self.getvalue(arg2)
+
+        # replace "x / const" by "x * (1/const)" if possible
+        if v2.is_constant():
+            divisor = v2.box.getfloat()
+            fraction = math.frexp(divisor)[0]
+            # This optimization is valid for powers of two
+            # but not for zeroes, some denormals and NaN:
+            if fraction == 0.5 or fraction == -0.5:
+                reciprocal = 1.0 / divisor
+                rfraction = math.frexp(reciprocal)[0]
+                if rfraction == 0.5 or rfraction == -0.5:
+                    c = ConstFloat(longlong.getfloatstorage(reciprocal))
+                    op = op.copy_and_change(rop.FLOAT_MUL, args=[arg1, c])
+        self.emit_operation(op)
+
     def optimize_FLOAT_NEG(self, op):
         v1 = op.getarg(0)
         self.emit_operation(op)
diff --git a/rpython/jit/metainterp/optimizeopt/test/test_optimizebasic.py 
b/rpython/jit/metainterp/optimizeopt/test/test_optimizebasic.py
--- a/rpython/jit/metainterp/optimizeopt/test/test_optimizebasic.py
+++ b/rpython/jit/metainterp/optimizeopt/test/test_optimizebasic.py
@@ -2364,6 +2364,28 @@
         """
         self.optimize_loop(ops, expected)
 
+    def test_float_division_by_multiplication(self):
+        ops = """
+        [f0]
+        f1 = float_truediv(f0, 2.0)
+        f2 = float_truediv(f1, 3.0)
+        f3 = float_truediv(f2, -0.25)
+        f4 = float_truediv(f3, 0.0)
+        f5 = escape(f4)
+        jump(f5)
+        """
+
+        expected = """
+        [f0]
+        f1 = float_mul(f0, 0.5)
+        f2 = float_truediv(f1, 3.0)
+        f3 = float_mul(f2, -4.0)
+        f4 = float_truediv(f3, 0.0)
+        f5 = escape(f4)
+        jump(f5)
+        """
+        self.optimize_loop(ops, expected)
+
     # ----------
 
     def _verify_fail_args(self, boxes, oparse, text):
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
@@ -1333,8 +1333,6 @@
             while True:
                 pc = self.pc
                 op = ord(self.bytecode[pc])
-                #debug_print(self.jitcode.name, pc)
-                #print staticdata.opcode_names[op]
                 staticdata.opcode_implementations[op](self, pc)
         except ChangeFrame:
             pass
diff --git a/rpython/jit/metainterp/test/test_rawmem.py 
b/rpython/jit/metainterp/test/test_rawmem.py
--- a/rpython/jit/metainterp/test/test_rawmem.py
+++ b/rpython/jit/metainterp/test/test_rawmem.py
@@ -89,6 +89,16 @@
                                        'finish': 1})
         self.metainterp.staticdata.stats.check_resops({'finish': 1}, 
omit_finish=False)
 
+    def test_scoped_alloc_buffer(self):
+        def f():
+            with rffi.scoped_alloc_buffer(42) as p:
+                p.raw[0] = 'X'
+                s = p.str(1)
+            return ord(s[0])
+
+        res = self.interp_operations(f, [])
+        assert res == ord('X')
+
 
 class TestRawMem(RawMemTests, LLJitMixin):
 
diff --git a/rpython/rlib/_rsocket_rffi.py b/rpython/rlib/_rsocket_rffi.py
--- a/rpython/rlib/_rsocket_rffi.py
+++ b/rpython/rlib/_rsocket_rffi.py
@@ -499,7 +499,7 @@
 getnameinfo = external('getnameinfo', [sockaddr_ptr, socklen_t, CCHARP,
                        size_t, CCHARP, size_t, rffi.INT], rffi.INT)
 
-if sys.platform.startswith("openbsd"):
+if sys.platform.startswith("openbsd") or sys.platform.startswith("darwin"):
     htonl = external('htonl', [rffi.UINT], rffi.UINT, releasegil=False, 
macro=True)
     htons = external('htons', [rffi.USHORT], rffi.USHORT, releasegil=False, 
macro=True)
     ntohl = external('ntohl', [rffi.UINT], rffi.UINT, releasegil=False, 
macro=True)
diff --git a/rpython/rlib/rfile.py b/rpython/rlib/rfile.py
--- a/rpython/rlib/rfile.py
+++ b/rpython/rlib/rfile.py
@@ -96,9 +96,12 @@
 c_ferror = llexternal('ferror', [FILEP], rffi.INT)
 c_clearerr = llexternal('clearerr', [FILEP], lltype.Void)
 
-c_stdin = rffi.CExternVariable(FILEP, 'stdin', eci, c_type='FILE*')[0]
-c_stdout = rffi.CExternVariable(FILEP, 'stdout', eci, c_type='FILE*')[0]
-c_stderr = rffi.CExternVariable(FILEP, 'stderr', eci, c_type='FILE*')[0]
+c_stdin = rffi.CExternVariable(FILEP, 'stdin', eci, c_type='FILE*',
+                               getter_only=True)
+c_stdout = rffi.CExternVariable(FILEP, 'stdout', eci, c_type='FILE*',
+                                getter_only=True)
+c_stderr = rffi.CExternVariable(FILEP, 'stderr', eci, c_type='FILE*',
+                                getter_only=True)
 
 
 def _error(ll_file):
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
@@ -605,7 +605,7 @@
 
 def CExternVariable(TYPE, name, eci, _CConstantClass=CConstant,
                     sandboxsafe=False, _nowrapper=False,
-                    c_type=None):
+                    c_type=None, getter_only=False):
     """Return a pair of functions - a getter and a setter - to access
     the given global C variable.
     """
@@ -638,19 +638,26 @@
     if sys.platform != 'win32':
         lines.append('extern %s %s;' % (c_type, name))
     lines.append(c_getter)
-    lines.append(c_setter)
+    if not getter_only:
+        lines.append(c_setter)
+    prototypes = [getter_prototype]
+    if not getter_only:
+        prototypes.append(setter_prototype)
     sources = ('\n'.join(lines),)
     new_eci = eci.merge(ExternalCompilationInfo(
         separate_module_sources = sources,
-        post_include_bits = [getter_prototype, setter_prototype],
+        post_include_bits = prototypes,
     ))
 
     getter = llexternal(getter_name, [], TYPE, compilation_info=new_eci,
                         sandboxsafe=sandboxsafe, _nowrapper=_nowrapper)
-    setter = llexternal(setter_name, [TYPE], lltype.Void,
-                        compilation_info=new_eci, sandboxsafe=sandboxsafe,
-                        _nowrapper=_nowrapper)
-    return getter, setter
+    if getter_only:
+        return getter
+    else:
+        setter = llexternal(setter_name, [TYPE], lltype.Void,
+                            compilation_info=new_eci, sandboxsafe=sandboxsafe,
+                            _nowrapper=_nowrapper)
+        return getter, setter
 
 # char, represented as a Python character
 # (use SIGNEDCHAR or UCHAR for the small integer types)
@@ -815,6 +822,8 @@
     free_nonmovingbuffer._annenforceargs_ = [strtype, None, bool, bool]
 
     # int -> (char*, str, int)
+    # Can't inline this because of the raw address manipulation.
+    @jit.dont_look_inside
     def alloc_buffer(count):
         """
         Returns a (raw_buffer, gc_buffer, case_num) triple,
diff --git a/rpython/rtyper/rptr.py b/rpython/rtyper/rptr.py
--- a/rpython/rtyper/rptr.py
+++ b/rpython/rtyper/rptr.py
@@ -115,9 +115,9 @@
 
 class __extend__(pairtype(PtrRepr, PtrRepr)):
     def convert_from_to((r_ptr1, r_ptr2), v, llop):
-        assert r_ptr1.lowleveltype == r_ptr2.lowleveltype
-        return v
-
+        if r_ptr1.lowleveltype == r_ptr2.lowleveltype:
+            return v
+        return NotImplemented
 
 class __extend__(pairtype(PtrRepr, IntegerRepr)):
 
diff --git a/rpython/translator/c/src/libffi_msvc/ffi.h 
b/rpython/translator/c/src/libffi_msvc/ffi.h
--- a/rpython/translator/c/src/libffi_msvc/ffi.h
+++ b/rpython/translator/c/src/libffi_msvc/ffi.h
@@ -60,6 +60,7 @@
 
 /* ---- System configuration information --------------------------------- */
 
+#include <src/precommondefs.h> /* for RPY_EXPORTED_FOR_TESTS */
 #include <ffitarget.h>
 
 #ifndef LIBFFI_ASM
@@ -221,6 +222,7 @@
   void      *user_data;
 } ffi_closure;
 
+RPY_EXPORTED_FOR_TESTS
 ffi_status
 ffi_prep_closure (ffi_closure*,
                  ffi_cif *,
@@ -264,12 +266,14 @@
 
 /* ---- Public interface definition -------------------------------------- */
 
+RPY_EXPORTED_FOR_TESTS
 ffi_status ffi_prep_cif(/*@out@*/ /*@partial@*/ ffi_cif *cif, 
                        ffi_abi abi,
                        unsigned int nargs, 
                        /*@dependent@*/ /*@out@*/ /*@partial@*/ ffi_type 
*rtype, 
                        /*@dependent@*/ ffi_type **atypes);
 
+RPY_EXPORTED_FOR_TESTS
 int
 ffi_call(/*@dependent@*/ ffi_cif *cif, 
         void (*fn)(), 
diff --git a/rpython/translator/c/src/profiling.c 
b/rpython/translator/c/src/profiling.c
--- a/rpython/translator/c/src/profiling.c
+++ b/rpython/translator/c/src/profiling.c
@@ -10,7 +10,7 @@
 static int profiling_setup = 0;
 
 RPY_EXPORTED_FOR_TESTS
-void pypy_setup_profiling()
+void pypy_setup_profiling(void)
 {
   if (!profiling_setup) {
     cpu_set_t set;
@@ -23,7 +23,7 @@
 }
 
 RPY_EXPORTED_FOR_TESTS
-void pypy_teardown_profiling()
+void pypy_teardown_profiling(void)
 {
   if (profiling_setup) {
     sched_setaffinity(0, sizeof(cpu_set_t), &base_cpu_set);
@@ -40,7 +40,8 @@
 static DWORD_PTR base_affinity_mask;
 static int profiling_setup = 0;
 
-void pypy_setup_profiling() { 
+RPY_EXPORTED_FOR_TESTS
+void pypy_setup_profiling(void) {
     if (!profiling_setup) {
         DWORD_PTR affinity_mask, system_affinity_mask;
         GetProcessAffinityMask(GetCurrentProcess(),
@@ -55,7 +56,8 @@
     }
 }
 
-void pypy_teardown_profiling() {
+RPY_EXPORTED_FOR_TESTS
+void pypy_teardown_profiling(void) {
     if (profiling_setup) {
         SetProcessAffinityMask(GetCurrentProcess(), base_affinity_mask);
         profiling_setup = 0;
@@ -65,7 +67,7 @@
 #else
 
 /* Empty implementations for other platforms */
-void pypy_setup_profiling() { }
-void pypy_teardown_profiling() { }
+RPY_EXPORTED_FOR_TESTS void pypy_setup_profiling(void) { }
+RPY_EXPORTED_FOR_TESTS void pypy_teardown_profiling(void) { }
 
 #endif
diff --git a/rpython/translator/c/src/profiling.h 
b/rpython/translator/c/src/profiling.h
--- a/rpython/translator/c/src/profiling.h
+++ b/rpython/translator/c/src/profiling.h
@@ -1,7 +1,7 @@
 #ifndef _PYPY_PROFILING_H
 #define _PYPY_PROFILING_H
 
-void pypy_setup_profiling();
-void pypy_teardown_profiling();
+RPY_EXPORTED_FOR_TESTS void pypy_setup_profiling(void);
+RPY_EXPORTED_FOR_TESTS void pypy_teardown_profiling(void);
 
 #endif
diff --git a/rpython/translator/simplify.py b/rpython/translator/simplify.py
--- a/rpython/translator/simplify.py
+++ b/rpython/translator/simplify.py
@@ -5,6 +5,7 @@
 simplify_graph() applies all simplifications defined in this file.
 """
 import py
+from collections import defaultdict
 
 from rpython.flowspace.model import (Variable, Constant,
                                      c_last_exception, checkgraph, mkentrymap)
@@ -401,8 +402,8 @@
 def transform_dead_op_vars_in_blocks(blocks, graphs, translator=None):
     """Remove dead operations and variables that are passed over a link
     but not used in the target block. Input is a set of blocks"""
-    read_vars = {}  # set of variables really used
-    variable_flow = {}  # map {Var: list-of-Vars-it-depends-on}
+    read_vars = set()  # set of variables really used
+    dependencies = defaultdict(set) # map {Var: list-of-Vars-it-depends-on}
     set_of_blocks = set(blocks)
     start_blocks = find_start_blocks(graphs)
 
@@ -414,53 +415,48 @@
         # cannot remove the exc-raising operation
         return op is not block.operations[-1]
 
-    # compute variable_flow and an initial read_vars
+    # compute dependencies and an initial read_vars
     for block in blocks:
         # figure out which variables are ever read
         for op in block.operations:
-            if not canremove(op, block):   # mark the inputs as really needed
-                for arg in op.args:
-                    read_vars[arg] = True
+            if not canremove(op, block):   # the inputs are always needed
+                read_vars.update(op.args)
             else:
-                # if CanRemove, only mark dependencies of the result
-                # on the input variables
-                deps = variable_flow.setdefault(op.result, [])
-                deps.extend(op.args)
+                dependencies[op.result].update(op.args)
 
         if isinstance(block.exitswitch, Variable):
-            read_vars[block.exitswitch] = True
+            read_vars.add(block.exitswitch)
 
         if block.exits:
             for link in block.exits:
                 if link.target not in set_of_blocks:
                     for arg, targetarg in zip(link.args, 
link.target.inputargs):
-                        read_vars[arg] = True
-                        read_vars[targetarg] = True
+                        read_vars.add(arg)
+                        read_vars.add(targetarg)
                 else:
                     for arg, targetarg in zip(link.args, 
link.target.inputargs):
-                        deps = variable_flow.setdefault(targetarg, [])
-                        deps.append(arg)
+                        dependencies[targetarg].add(arg)
         else:
             # return and except blocks implicitely use their input variable(s)
             for arg in block.inputargs:
-                read_vars[arg] = True
-        # an input block's inputargs should not be modified, even if some
+                read_vars.add(arg)
+        # a start block's inputargs should not be modified, even if some
         # of the function's input arguments are not actually used
         if block in start_blocks:
             for arg in block.inputargs:
-                read_vars[arg] = True
+                read_vars.add(arg)
 
     # flow read_vars backwards so that any variable on which a read_vars
     # depends is also included in read_vars
     def flow_read_var_backward(pending):
-        pending = list(pending)
-        for var in pending:
-            for prevvar in variable_flow.get(var, []):
+        while pending:
+            var = pending.pop()
+            for prevvar in dependencies[var]:
                 if prevvar not in read_vars:
-                    read_vars[prevvar] = True
-                    pending.append(prevvar)
+                    read_vars.add(prevvar)
+                    pending.add(prevvar)
 
-    flow_read_var_backward(read_vars)
+    flow_read_var_backward(set(read_vars))
 
     for block in blocks:
 
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to