Author: Ronan Lamy <[email protected]>
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
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit