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