[pypy-commit] pypy jit-singlefloat: Front-end support for singlefloats.
arigo
noreply at buildbot.pypy.org
Thu Jul 28 21:47:37 CEST 2011
Author: Armin Rigo <arigo at tunes.org>
Branch: jit-singlefloat
Changeset: r46059:af30af85a7b1
Date: 2011-07-28 15:52 +0200
http://bitbucket.org/pypy/pypy/changeset/af30af85a7b1/
Log: Front-end support for singlefloats.
diff --git a/pypy/jit/backend/llgraph/runner.py b/pypy/jit/backend/llgraph/runner.py
--- a/pypy/jit/backend/llgraph/runner.py
+++ b/pypy/jit/backend/llgraph/runner.py
@@ -91,6 +91,7 @@
class BaseCPU(model.AbstractCPU):
supports_floats = True
supports_longlong = llimpl.IS_32_BIT
+ supports_singlefloats = True
def __init__(self, rtyper, stats=None, opts=None,
translate_support_code=False,
diff --git a/pypy/jit/codewriter/jtransform.py b/pypy/jit/codewriter/jtransform.py
--- a/pypy/jit/codewriter/jtransform.py
+++ b/pypy/jit/codewriter/jtransform.py
@@ -9,7 +9,7 @@
from pypy.objspace.flow.model import SpaceOperation, Variable, Constant, c_last_exception
from pypy.rlib import objectmodel
from pypy.rlib.jit import _we_are_jitted
-from pypy.rpython.lltypesystem import lltype, llmemory, rstr, rclass
+from pypy.rpython.lltypesystem import lltype, llmemory, rstr, rclass, rffi
from pypy.rpython.rclass import IR_QUASIIMMUTABLE, IR_QUASIIMMUTABLE_ARRAY
from pypy.translator.simplify import get_funcobj
from pypy.translator.unsimplify import varoftype
@@ -785,7 +785,6 @@
op2.result = op.result
return op2
elif toll:
- from pypy.rpython.lltypesystem import rffi
size, unsigned = rffi.size_and_sign(op.args[0].concretetype)
if unsigned:
INTERMEDIATE = lltype.Unsigned
@@ -807,20 +806,27 @@
return self.force_cast_without_longlong(op.args[0], op.result)
def force_cast_without_longlong(self, v_arg, v_result):
- from pypy.rpython.lltypesystem.rffi import size_and_sign, sizeof, FLOAT
- #
- if (v_result.concretetype in (FLOAT, lltype.Float) or
- v_arg.concretetype in (FLOAT, lltype.Float)):
- assert (v_result.concretetype == lltype.Float and
- v_arg.concretetype == lltype.Float), "xxx unsupported cast"
+ if v_result.concretetype == v_arg.concretetype:
return
- #
- size2, unsigned2 = size_and_sign(v_result.concretetype)
- assert size2 <= sizeof(lltype.Signed)
- if size2 == sizeof(lltype.Signed):
+ if v_arg.concretetype == rffi.FLOAT:
+ assert v_result.concretetype == lltype.Float, "cast %s -> %s" % (
+ v_arg.concretetype, v_result.concretetype)
+ return SpaceOperation('cast_singlefloat_to_float', [v_arg],
+ v_result)
+ if v_result.concretetype == rffi.FLOAT:
+ assert v_arg.concretetype == lltype.Float, "cast %s -> %s" % (
+ v_arg.concretetype, v_result.concretetype)
+ return SpaceOperation('cast_float_to_singlefloat', [v_arg],
+ v_result)
+ return self.force_cast_without_singlefloat(v_arg, v_result)
+
+ def force_cast_without_singlefloat(self, v_arg, v_result):
+ size2, unsigned2 = rffi.size_and_sign(v_result.concretetype)
+ assert size2 <= rffi.sizeof(lltype.Signed)
+ if size2 == rffi.sizeof(lltype.Signed):
return # the target type is LONG or ULONG
- size1, unsigned1 = size_and_sign(v_arg.concretetype)
- assert size1 <= sizeof(lltype.Signed)
+ size1, unsigned1 = rffi.size_and_sign(v_arg.concretetype)
+ assert size1 <= rffi.sizeof(lltype.Signed)
#
def bounds(size, unsigned):
if unsigned:
@@ -849,7 +855,6 @@
return result
def rewrite_op_direct_ptradd(self, op):
- from pypy.rpython.lltypesystem import rffi
# xxx otherwise, not implemented:
assert op.args[0].concretetype == rffi.CCHARP
#
diff --git a/pypy/jit/codewriter/policy.py b/pypy/jit/codewriter/policy.py
--- a/pypy/jit/codewriter/policy.py
+++ b/pypy/jit/codewriter/policy.py
@@ -12,6 +12,7 @@
self.unsafe_loopy_graphs = set()
self.supports_floats = False
self.supports_longlong = False
+ self.supports_singlefloats = False
def set_supports_floats(self, flag):
self.supports_floats = flag
@@ -19,6 +20,9 @@
def set_supports_longlong(self, flag):
self.supports_longlong = flag
+ def set_supports_singlefloats(self, flag):
+ self.supports_singlefloats = flag
+
def dump_unsafe_loops(self):
f = udir.join("unsafe-loops.txt").open('w')
strs = [str(graph) for graph in self.unsafe_loopy_graphs]
@@ -58,8 +62,9 @@
func, '_jit_unroll_safe_', False)
unsupported = contains_unsupported_variable_type(graph,
- self.supports_floats,
- self.supports_longlong)
+ self.supports_floats,
+ self.supports_longlong,
+ self.supports_singlefloats)
res = see_function and not unsupported
if res and contains_loop:
self.unsafe_loopy_graphs.add(graph)
@@ -80,17 +85,24 @@
return res
def contains_unsupported_variable_type(graph, supports_floats,
- supports_longlong):
+ supports_longlong,
+ supports_singlefloats):
getkind = history.getkind
try:
for block in graph.iterblocks():
for v in block.inputargs:
- getkind(v.concretetype, supports_floats, supports_longlong)
+ getkind(v.concretetype, supports_floats,
+ supports_longlong,
+ supports_singlefloats)
for op in block.operations:
for v in op.args:
- getkind(v.concretetype, supports_floats, supports_longlong)
+ getkind(v.concretetype, supports_floats,
+ supports_longlong,
+ supports_singlefloats)
v = op.result
- getkind(v.concretetype, supports_floats, supports_longlong)
+ getkind(v.concretetype, supports_floats,
+ supports_longlong,
+ supports_singlefloats)
except NotImplementedError, e:
log.WARNING('%s, ignoring graph' % (e,))
log.WARNING(' %s' % (graph,))
diff --git a/pypy/jit/codewriter/test/test_policy.py b/pypy/jit/codewriter/test/test_policy.py
--- a/pypy/jit/codewriter/test/test_policy.py
+++ b/pypy/jit/codewriter/test/test_policy.py
@@ -12,24 +12,30 @@
graph = support.getgraph(f, [5])
for sf in [False, True]:
for sll in [False, True]:
- assert not contains_unsupported_variable_type(graph, sf, sll)
+ for ssf in [False, True]:
+ assert not contains_unsupported_variable_type(graph, sf,
+ sll, ssf)
#
graph = support.getgraph(f, [5.5])
for sf in [False, True]:
for sll in [False, True]:
- res = contains_unsupported_variable_type(graph, sf, sll)
- assert res is not sf
+ for ssf in [False, True]:
+ res = contains_unsupported_variable_type(graph, sf, sll, ssf)
+ assert res is not sf
#
graph = support.getgraph(f, [r_singlefloat(5.5)])
for sf in [False, True]:
for sll in [False, True]:
- assert contains_unsupported_variable_type(graph, sf, sll)
+ for ssf in [False, True]:
+ res = contains_unsupported_variable_type(graph, sf, sll, ssf)
+ assert res == (not ssf)
#
graph = support.getgraph(f, [r_longlong(5)])
for sf in [False, True]:
for sll in [False, True]:
- res = contains_unsupported_variable_type(graph, sf, sll)
- assert res == (sys.maxint == 2147483647 and not sll)
+ for ssf in [False, True]:
+ res = contains_unsupported_variable_type(graph, sf, sll, ssf)
+ assert res == (sys.maxint == 2147483647 and not sll)
def test_regular_function():
diff --git a/pypy/jit/metainterp/blackhole.py b/pypy/jit/metainterp/blackhole.py
--- a/pypy/jit/metainterp/blackhole.py
+++ b/pypy/jit/metainterp/blackhole.py
@@ -623,6 +623,23 @@
x = float(a)
return longlong.getfloatstorage(x)
+ @arguments("f", returns="i")
+ def bhimpl_cast_float_to_singlefloat(a):
+ from pypy.rlib.rarithmetic import r_singlefloat
+ from pypy.rlib.longlong2float import singlefloat2uint
+ a = longlong.getrealfloat(a)
+ a = r_singlefloat(a)
+ a = singlefloat2uint(a)
+ return intmask(a)
+
+ @arguments("i", returns="f")
+ def bhimpl_cast_singlefloat_to_float(a):
+ from pypy.rpython.lltypesystem.rffi import r_uint
+ from pypy.rlib.longlong2float import uint2singlefloat
+ a = uint2singlefloat(r_uint(a))
+ a = float(a)
+ return longlong.getfloatstorage(a)
+
# ----------
# control flow operations
diff --git a/pypy/jit/metainterp/history.py b/pypy/jit/metainterp/history.py
--- a/pypy/jit/metainterp/history.py
+++ b/pypy/jit/metainterp/history.py
@@ -20,12 +20,16 @@
FAILARGS_LIMIT = 1000
-def getkind(TYPE, supports_floats=True, supports_longlong=True):
+def getkind(TYPE, supports_floats=True,
+ supports_longlong=True,
+ supports_singlefloats=True):
if TYPE is lltype.Void:
return "void"
elif isinstance(TYPE, lltype.Primitive):
if TYPE is lltype.Float and supports_floats:
return 'float'
+ if TYPE is lltype.SingleFloat and supports_singlefloats:
+ return 'int' # singlefloats are stored in an int
if TYPE in (lltype.Float, lltype.SingleFloat):
raise NotImplementedError("type %s not supported" % TYPE)
# XXX fix this for oo...
diff --git a/pypy/jit/metainterp/pyjitpl.py b/pypy/jit/metainterp/pyjitpl.py
--- a/pypy/jit/metainterp/pyjitpl.py
+++ b/pypy/jit/metainterp/pyjitpl.py
@@ -215,6 +215,7 @@
for _opimpl in ['int_is_true', 'int_is_zero', 'int_neg', 'int_invert',
'cast_float_to_int', 'cast_int_to_float',
+ 'cast_float_to_singlefloat', 'cast_singlefloat_to_float',
'float_neg', 'float_abs',
]:
exec py.code.Source('''
diff --git a/pypy/jit/metainterp/resoperation.py b/pypy/jit/metainterp/resoperation.py
--- a/pypy/jit/metainterp/resoperation.py
+++ b/pypy/jit/metainterp/resoperation.py
@@ -408,6 +408,8 @@
'FLOAT_ABS/1',
'CAST_FLOAT_TO_INT/1',
'CAST_INT_TO_FLOAT/1',
+ 'CAST_FLOAT_TO_SINGLEFLOAT/1',
+ 'CAST_SINGLEFLOAT_TO_FLOAT/1',
#
'INT_LT/2b',
'INT_LE/2b',
diff --git a/pypy/jit/metainterp/test/test_float.py b/pypy/jit/metainterp/test/test_float.py
--- a/pypy/jit/metainterp/test/test_float.py
+++ b/pypy/jit/metainterp/test/test_float.py
@@ -36,6 +36,15 @@
res = self.interp_operations(f, [x])
assert res == -x
+ def test_singlefloat(self):
+ from pypy.rlib.rarithmetic import r_singlefloat
+ def f(a):
+ a = float(r_singlefloat(a))
+ a *= 4.25
+ return float(r_singlefloat(a))
+ res = self.interp_operations(f, [-2.0])
+ assert res == -8.5
+
class TestOOtype(FloatTests, OOJitMixin):
pass
diff --git a/pypy/jit/metainterp/warmspot.py b/pypy/jit/metainterp/warmspot.py
--- a/pypy/jit/metainterp/warmspot.py
+++ b/pypy/jit/metainterp/warmspot.py
@@ -173,6 +173,7 @@
policy = JitPolicy()
policy.set_supports_floats(self.cpu.supports_floats)
policy.set_supports_longlong(self.cpu.supports_longlong)
+ policy.set_supports_singlefloats(self.cpu.supports_singlefloats)
graphs = self.codewriter.find_all_graphs(policy)
policy.dump_unsafe_loops()
self.check_access_directly_sanity(graphs)
diff --git a/pypy/rlib/longlong2float.py b/pypy/rlib/longlong2float.py
--- a/pypy/rlib/longlong2float.py
+++ b/pypy/rlib/longlong2float.py
@@ -11,7 +11,7 @@
# -------- implement longlong2float and float2longlong --------
DOUBLE_ARRAY_PTR = lltype.Ptr(lltype.Array(rffi.DOUBLE))
LONGLONG_ARRAY_PTR = lltype.Ptr(lltype.Array(rffi.LONGLONG))
-INT_ARRAY_PTR = lltype.Ptr(lltype.Array(rffi.INT))
+UINT_ARRAY_PTR = lltype.Ptr(lltype.Array(rffi.UINT))
FLOAT_ARRAY_PTR = lltype.Ptr(lltype.Array(rffi.FLOAT))
# these definitions are used only in tests, when not translated
@@ -31,17 +31,17 @@
lltype.free(d_array, flavor='raw')
return llval
-def int2singlefloat_emulator(ival):
+def uint2singlefloat_emulator(ival):
f_array = lltype.malloc(FLOAT_ARRAY_PTR.TO, 1, flavor='raw')
- i_array = rffi.cast(INT_ARRAY_PTR, f_array)
+ i_array = rffi.cast(UINT_ARRAY_PTR, f_array)
i_array[0] = ival
singlefloatval = f_array[0]
lltype.free(f_array, flavor='raw')
return singlefloatval
-def singlefloat2int_emulator(singlefloatval):
+def singlefloat2uint_emulator(singlefloatval):
f_array = lltype.malloc(FLOAT_ARRAY_PTR.TO, 1, flavor='raw')
- i_array = rffi.cast(INT_ARRAY_PTR, f_array)
+ i_array = rffi.cast(UINT_ARRAY_PTR, f_array)
f_array[0] = singlefloatval
ival = i_array[0]
lltype.free(f_array, flavor='raw')
@@ -62,15 +62,15 @@
memcpy(&ll, &x, 8);
return ll;
}
-static float pypy__int2singlefloat(int x) {
+static float pypy__uint2singlefloat(unsigned int x) {
float ff;
- assert(sizeof(float) == 4 && sizeof(int) == 4);
+ assert(sizeof(float) == 4 && sizeof(unsigned int) == 4);
memcpy(&ff, &x, 4);
return ff;
}
-static int pypy__singlefloat2int(float x) {
- int ii;
- assert(sizeof(float) == 4 && sizeof(int) == 4);
+static unsigned int pypy__singlefloat2uint(float x) {
+ unsigned int ii;
+ assert(sizeof(float) == 4 && sizeof(unsigned int) == 4);
memcpy(&ii, &x, 4);
return ii;
}
@@ -86,12 +86,12 @@
_callable=float2longlong_emulator, compilation_info=eci,
_nowrapper=True, elidable_function=True)
-int2singlefloat = rffi.llexternal(
- "pypy__int2singlefloat", [rffi.INT], rffi.FLOAT,
- _callable=int2singlefloat_emulator, compilation_info=eci,
+uint2singlefloat = rffi.llexternal(
+ "pypy__uint2singlefloat", [rffi.UINT], rffi.FLOAT,
+ _callable=uint2singlefloat_emulator, compilation_info=eci,
_nowrapper=True, elidable_function=True)
-singlefloat2int = rffi.llexternal(
- "pypy__singlefloat2int", [rffi.FLOAT], rffi.INT,
- _callable=singlefloat2int_emulator, compilation_info=eci,
+singlefloat2uint = rffi.llexternal(
+ "pypy__singlefloat2uint", [rffi.FLOAT], rffi.UINT,
+ _callable=singlefloat2uint_emulator, compilation_info=eci,
_nowrapper=True, elidable_function=True)
diff --git a/pypy/rlib/test/test_longlong2float.py b/pypy/rlib/test/test_longlong2float.py
--- a/pypy/rlib/test/test_longlong2float.py
+++ b/pypy/rlib/test/test_longlong2float.py
@@ -1,6 +1,6 @@
from pypy.translator.c.test.test_genc import compile
from pypy.rlib.longlong2float import longlong2float, float2longlong
-from pypy.rlib.longlong2float import int2singlefloat, singlefloat2int
+from pypy.rlib.longlong2float import uint2singlefloat, singlefloat2uint
from pypy.rlib.rarithmetic import r_singlefloat
@@ -35,8 +35,8 @@
def fnsingle(f1):
sf1 = r_singlefloat(f1)
- ii = singlefloat2int(sf1)
- sf2 = int2singlefloat(ii)
+ ii = singlefloat2uint(sf1)
+ sf2 = uint2singlefloat(ii)
f2 = float(sf2)
return f2
More information about the pypy-commit
mailing list