[pypy-commit] pypy jitframe-on-heap: merge default
fijal
noreply at buildbot.pypy.org
Sat Jan 12 16:03:08 CET 2013
Author: Maciej Fijalkowski <fijall at gmail.com>
Branch: jitframe-on-heap
Changeset: r59989:f3cfd5e2c1e3
Date: 2013-01-12 17:02 +0200
http://bitbucket.org/pypy/pypy/changeset/f3cfd5e2c1e3/
Log: merge default
diff --git a/pypy/doc/test/test_whatsnew.py b/pypy/doc/test/test_whatsnew.py
--- a/pypy/doc/test/test_whatsnew.py
+++ b/pypy/doc/test/test_whatsnew.py
@@ -29,7 +29,7 @@
merge() and \
branch(default)) and \
not branch(default)' % (startrev, endrev)
- cmd = r"hg log -R '%s' -r '%s' --template '{branches}\n'" % (path, revset)
+ cmd = r'hg log -R "%s" -r "%s" --template "{branches}\n"' % (path, revset)
out = getoutput(cmd)
branches = set(map(str.strip, out.splitlines()))
return branches
diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst
--- a/pypy/doc/whatsnew-head.rst
+++ b/pypy/doc/whatsnew-head.rst
@@ -15,6 +15,9 @@
.. branch: numpypy-longdouble
Long double support for numpypy
+.. branch: numpypy-real-as-view
+Convert real, imag from ufuncs to views. This involves the beginning of
+view() functionality
.. branch: signatures
Improved RPython typing
diff --git a/pypy/interpreter/pyopcode.py b/pypy/interpreter/pyopcode.py
--- a/pypy/interpreter/pyopcode.py
+++ b/pypy/interpreter/pyopcode.py
@@ -178,6 +178,11 @@
else:
oparg = 0
+ # note: the structure of the code here is such that it makes
+ # (after translation) a big "if/elif" chain, which is then
+ # turned into a switch(). It starts here: even if the first
+ # one is not an "if" but a "while" the effect is the same.
+
while opcode == self.opcodedesc.EXTENDED_ARG.index:
opcode = ord(co_code[next_instr])
if opcode < self.HAVE_ARGUMENT:
@@ -226,6 +231,8 @@
'END_FINALLY', 'JUMP_ABSOLUTE'):
continue # opcodes implemented above
+ # the following "if" is part of the big switch described
+ # above.
if opcode == opdesc.index:
# dispatch to the opcode method
meth = getattr(self, opdesc.methodname)
diff --git a/pypy/jit/backend/test/calling_convention_test.py b/pypy/jit/backend/test/calling_convention_test.py
--- a/pypy/jit/backend/test/calling_convention_test.py
+++ b/pypy/jit/backend/test/calling_convention_test.py
@@ -105,11 +105,13 @@
ops = '[%s]\n' % arguments
ops += '%s\n' % spill_ops
ops += 'f99 = call(ConstClass(func_ptr), %s, descr=calldescr)\n' % arguments
- ops += 'finish(f99, %s)\n' % arguments
+ ops += 'i99 = same_as(0)\n'
+ ops += 'guard_true(i99) [f99, %s]\n' % arguments
+ ops += 'finish()\n'
loop = parse(ops, namespace=locals())
looptoken = JitCellToken()
- done_number = self.cpu.get_fail_descr_number(loop.operations[-1].getdescr())
+ done_number = self.cpu.get_fail_descr_number(loop.operations[-2].getdescr())
self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken)
argvals, expected_result = self._prepare_args(args, floats, ints)
diff --git a/pypy/jit/backend/test/runner_test.py b/pypy/jit/backend/test/runner_test.py
--- a/pypy/jit/backend/test/runner_test.py
+++ b/pypy/jit/backend/test/runner_test.py
@@ -1168,7 +1168,8 @@
values.append(longlong.getfloatstorage(r.random()))
#
looptoken = JitCellToken()
- faildescr = BasicFinalDescr(42)
+ guarddescr = BasicFailDescr(42)
+ faildescr = BasicFinalDescr(43)
operations = []
retboxes = []
retvalues = []
@@ -1197,9 +1198,13 @@
retboxes.insert(kk, newbox)
retvalues.insert(kk, y)
#
- operations.append(
- ResOperation(rop.FINISH, retboxes, None, descr=faildescr)
- )
+ zero = BoxInt()
+ operations.extend([
+ ResOperation(rop.SAME_AS, [ConstInt(0)], zero),
+ ResOperation(rop.GUARD_TRUE, [zero], None, descr=guarddescr),
+ ResOperation(rop.FINISH, [], None, descr=faildescr)
+ ])
+ operations[-2].setfailargs(retboxes)
print inputargs
for op in operations:
print op
@@ -1319,13 +1324,16 @@
i2 = BoxInt()
targettoken = TargetToken()
faildescr1 = BasicFailDescr(1)
- faildescr2 = BasicFinalDescr(2)
+ faildescr2 = BasicFailDescr(2)
+ faildescr3 = BasicFinalDescr(3)
operations = [
ResOperation(rop.LABEL, fboxes, None, descr=targettoken),
ResOperation(rop.FLOAT_LE, [fboxes[0], constfloat(9.2)], i2),
ResOperation(rop.GUARD_TRUE, [i2], None, descr=faildescr1),
- ResOperation(rop.FINISH, fboxes, None, descr=faildescr2),
+ ResOperation(rop.GUARD_FALSE, [i2], None, descr=faildescr2),
+ ResOperation(rop.FINISH, [], None, descr=faildescr3),
]
+ operations[-3].setfailargs(fboxes)
operations[-2].setfailargs(fboxes)
looptoken = JitCellToken()
self.cpu.compile_loop(fboxes, operations, looptoken)
@@ -1357,7 +1365,8 @@
if not self.cpu.supports_floats:
py.test.skip("requires floats")
fboxes = [BoxFloat() for i in range(3)]
- faildescr1 = BasicFinalDescr(100)
+ faildescr1 = BasicFailDescr(100)
+ faildescr2 = BasicFinalDescr(102)
loopops = """
[i0,f1, f2]
f3 = float_add(f1, f2)
@@ -1382,9 +1391,13 @@
assert longlong.getrealfloat(f2) == 0.75
assert longlong.getrealfloat(f3) == 133.0
+ zero = BoxInt()
bridgeops = [
- ResOperation(rop.FINISH, fboxes, None, descr=faildescr1),
+ ResOperation(rop.SAME_AS, [ConstInt(0)], zero),
+ ResOperation(rop.GUARD_TRUE, [zero], None, descr=faildescr1),
+ ResOperation(rop.FINISH, [], None, descr=faildescr2),
]
+ bridgeops[-2].setfailargs(fboxes[:])
self.cpu.compile_bridge(loop.operations[-2].getdescr(), fboxes,
bridgeops, looptoken)
args = [1,
@@ -1978,7 +1991,7 @@
i1 = same_as(1)
call(ConstClass(fptr), i0, descr=calldescr)
p0 = guard_exception(ConstClass(xtp)) [i1]
- finish(0, p0)
+ finish(p0)
'''
FPTR = lltype.Ptr(lltype.FuncType([lltype.Signed], lltype.Void))
fptr = llhelper(FPTR, func)
@@ -1999,8 +2012,7 @@
looptoken = JitCellToken()
self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken)
deadframe = self.cpu.execute_token(looptoken, 1)
- assert self.cpu.get_int_value(deadframe, 0) == 0
- assert self.cpu.get_ref_value(deadframe, 1) == xptr
+ assert self.cpu.get_ref_value(deadframe, 0) == xptr
excvalue = self.cpu.grab_exc_value(deadframe)
assert not excvalue
deadframe = self.cpu.execute_token(looptoken, 0)
diff --git a/pypy/jit/backend/x86/test/test_recompilation.py b/pypy/jit/backend/x86/test/test_recompilation.py
--- a/pypy/jit/backend/x86/test/test_recompilation.py
+++ b/pypy/jit/backend/x86/test/test_recompilation.py
@@ -45,7 +45,8 @@
force_spill(i5)
i8 = int_add(i7, 1)
i9 = int_add(i8, 1)
- finish(i3, i4, i5, i6, i7, i8, i9, descr=fdescr2)
+ guard_false(i3, descr=fdescr2) [i3, i4, i5, i6, i7, i8, i9]
+ finish()
'''
bridge = self.attach_bridge(ops, loop, -2)
descr = loop.operations[3].getdescr()
diff --git a/pypy/jit/backend/x86/test/test_regalloc.py b/pypy/jit/backend/x86/test/test_regalloc.py
--- a/pypy/jit/backend/x86/test/test_regalloc.py
+++ b/pypy/jit/backend/x86/test/test_regalloc.py
@@ -327,7 +327,7 @@
assert self.getint(0) == 0
bridge_ops = '''
[i0, i1]
- finish(1, 2)
+ finish(2)
'''
self.attach_bridge(bridge_ops, loop, 0)
self.run(loop, 0, 1)
@@ -428,7 +428,7 @@
ops = '''
[i0, i1, i2, i3, i4, i5, i6, i7]
guard_value(i6, i1) [i0, i2, i3, i4, i5, i6]
- finish(i0, i2, i3, i4, i5, i6)
+ finish(i0)
'''
self.interpret(ops, [0, 0, 0, 0, 0, 0, 0, 0])
assert self.getint(0) == 0
@@ -438,14 +438,15 @@
[i0, i1, i2, i3, i4, i5, i6, i7, i8]
i9 = same_as(0)
guard_true(i0) [i9, i0, i1, i2, i3, i4, i5, i6, i7, i8]
- finish(1, i0, i1, i2, i3, i4, i5, i6, i7, i8)
+ finish(1)
'''
loop = self.interpret(ops, [0, 1, 2, 3, 4, 5, 6, 7, 8])
assert self.getint(0) == 0
bridge_ops = '''
[i9, i0, i1, i2, i3, i4, i5, i6, i7, i8]
call(ConstClass(raising_fptr), 0, descr=raising_calldescr)
- finish(i0, i1, i2, i3, i4, i5, i6, i7, i8)
+ guard_true(i9) [i0, i1, i2, i3, i4, i5, i6, i7, i8]
+ finish()
'''
self.attach_bridge(bridge_ops, loop, 1)
self.run(loop, 0, 1, 2, 3, 4, 5, 6, 7, 8)
@@ -474,7 +475,8 @@
i1 = same_as(1)
i2 = int_lt(i0, 100)
guard_true(i3) [i1, i2]
- finish(0, i2)
+ i4 = int_neg(i2)
+ finish(0)
'''
self.interpret(ops, [0, 1])
assert self.getint(0) == 0
@@ -503,7 +505,8 @@
i15 = int_is_true(i5)
i16 = int_is_true(i6)
i17 = int_is_true(i7)
- finish(i10, i11, i12, i13, i14, i15, i16, i17)
+ guard_true(i0) [i10, i11, i12, i13, i14, i15, i16, i17]
+ finish()
'''
self.interpret(ops, [0, 42, 12, 0, 13, 0, 0, 3333])
assert self.getints(8) == [0, 1, 1, 0, 1, 0, 0, 1]
@@ -517,7 +520,8 @@
i13 = int_eq(i5, i6)
i14 = int_gt(i6, i2)
i15 = int_ne(i2, i6)
- finish(i10, i11, i12, i13, i14, i15)
+ guard_true(i0) [i10, i11, i12, i13, i14, i15]
+ finish()
'''
self.interpret(ops, [0, 1, 2, 3, 4, 5, 6])
assert self.getints(6) == [1, 1, 0, 0, 1, 1]
@@ -574,7 +578,9 @@
ops = '''
[f0, f1]
f2 = float_add(f0, f1)
- finish(f2, f0, f1)
+ i0 = same_as(0)
+ guard_true(i0) [f2, f0, f1]
+ finish()
'''
self.interpret(ops, [3.0, 1.5])
assert self.getfloats(3) == [4.5, 3.0, 1.5]
@@ -584,7 +590,9 @@
[f0, f1, f2, f3, f4, f5, f6, f7, f8]
f9 = float_add(f0, f1)
f10 = float_add(f8, 3.5)
- finish(f9, f10, f2, f3, f4, f5, f6, f7, f8)
+ i0 = same_as(0)
+ guard_true(i0) [f9, f10, f2, f3, f4, f5, f6, f7, f8]
+ finish()
'''
self.interpret(ops, [0.1, .2, .3, .4, .5, .6, .7, .8, .9])
assert self.getfloats(9) == [.1+.2, .9+3.5, .3, .4, .5, .6, .7, .8, .9]
@@ -613,7 +621,8 @@
i7 = float_ne(f7, 0.0)
i8 = float_ne(f8, 0.0)
i9 = float_ne(f9, 0.0)
- finish(i0, i1, i2, i3, i4, i5, i6, i7, i8, i9)
+ guard_true(i0) [i0, i1, i2, i3, i4, i5, i6, i7, i8, i9]
+ finish()
'''
loop = self.interpret(ops, [0.0, .1, .2, .3, .4, .5, .6, .7, .8, .9])
assert self.getints(9) == [0, 1, 1, 1, 1, 1, 1, 1, 1]
diff --git a/pypy/jit/backend/x86/test/test_regalloc2.py b/pypy/jit/backend/x86/test/test_regalloc2.py
--- a/pypy/jit/backend/x86/test/test_regalloc2.py
+++ b/pypy/jit/backend/x86/test/test_regalloc2.py
@@ -11,13 +11,17 @@
v2 = BoxInt()
v3 = BoxInt()
v4 = BoxInt()
+ zero = BoxInt()
inputargs = [v1]
operations = [
ResOperation(rop.INT_ADD, [v1, v1], v2),
ResOperation(rop.INT_INVERT, [v2], v3),
ResOperation(rop.UINT_RSHIFT, [v1, ConstInt(3)], v4),
- ResOperation(rop.FINISH, [v4, v3], None, descr=BasicFailDescr()),
+ ResOperation(rop.SAME_AS, [ConstInt(0)], zero),
+ ResOperation(rop.GUARD_TRUE, [zero], None, descr=BasicFailDescr()),
+ ResOperation(rop.FINISH, [], None, descr=BasicFailDescr())
]
+ operations[-2].setfailargs([v4, v3])
cpu = CPU(None, None)
cpu.setup_once()
looptoken = JitCellToken()
@@ -31,6 +35,7 @@
v2 = BoxInt()
v3 = BoxInt()
v4 = BoxInt()
+ zero = BoxInt()
tmp5 = BoxInt()
inputargs = [v1]
operations = [
@@ -38,8 +43,11 @@
ResOperation(rop.INT_MUL, [v2, v1], v3),
ResOperation(rop.INT_IS_TRUE, [v2], tmp5),
ResOperation(rop.INT_IS_ZERO, [tmp5], v4),
- ResOperation(rop.FINISH, [v4, v3, tmp5], None, descr=BasicFailDescr()),
+ ResOperation(rop.SAME_AS, [ConstInt(0)], zero),
+ ResOperation(rop.GUARD_TRUE, [zero], None, descr=BasicFailDescr()),
+ ResOperation(rop.FINISH, [], None, descr=BasicFailDescr())
]
+ operations[-2].setfailargs([v4, v3, tmp5])
cpu = CPU(None, None)
cpu.setup_once()
looptoken = JitCellToken()
@@ -90,6 +98,7 @@
v38 = BoxInt()
v39 = BoxInt()
v40 = BoxInt()
+ zero = BoxInt()
tmp41 = BoxInt()
tmp42 = BoxInt()
tmp43 = BoxInt()
@@ -134,8 +143,12 @@
ResOperation(rop.UINT_GT, [v33, ConstInt(-11)], v38),
ResOperation(rop.INT_NEG, [v7], v39),
ResOperation(rop.INT_GT, [v24, v32], v40),
- ResOperation(rop.FINISH, [v40, v36, v37, v31, v16, v34, v35, v23, v22, v29, v14, v39, v30, v38], None, descr=BasicFailDescr()),
+ ResOperation(rop.SAME_AS, [ConstInt(0)], zero),
+ ResOperation(rop.GUARD_TRUE, [zero], None, descr=BasicFailDescr()),
+ ResOperation(rop.FINISH, [], None, descr=BasicFailDescr())
]
+ operations[-2].setfailargs([v40, v36, v37, v31, v16, v34, v35, v23,
+ v22, v29, v14, v39, v30, v38])
cpu = CPU(None, None)
cpu.setup_once()
looptoken = JitCellToken()
@@ -198,6 +211,7 @@
v38 = BoxInt()
v39 = BoxInt()
v40 = BoxInt()
+ zero = BoxInt()
tmp41 = BoxInt()
tmp42 = BoxInt()
tmp43 = BoxInt()
@@ -240,8 +254,13 @@
ResOperation(rop.INT_GT, [v4, v11], v38),
ResOperation(rop.INT_LT, [v27, v22], v39),
ResOperation(rop.INT_NEG, [v27], v40),
- ResOperation(rop.FINISH, [v40, v10, v36, v26, v13, v30, v21, v33, v18, v25, v31, v32, v28, v29, v35, v38, v20, v39, v34, v23, v37], None, descr=BasicFailDescr()),
+ ResOperation(rop.SAME_AS, [ConstInt(0)], zero),
+ ResOperation(rop.GUARD_TRUE, [zero], None, descr=BasicFailDescr()),
+ ResOperation(rop.FINISH, [], None, descr=BasicFailDescr())
]
+ operations[-2].setfailargs([v40, v10, v36, v26, v13, v30, v21, v33,
+ v18, v25, v31, v32, v28, v29, v35, v38,
+ v20, v39, v34, v23, v37])
cpu = CPU(None, None)
cpu.setup_once()
looptoken = JitCellToken()
diff --git a/pypy/jit/backend/x86/test/test_runner.py b/pypy/jit/backend/x86/test/test_runner.py
--- a/pypy/jit/backend/x86/test/test_runner.py
+++ b/pypy/jit/backend/x86/test/test_runner.py
@@ -499,9 +499,12 @@
i6, descr=calldescr),
ResOperation(rop.GUARD_NOT_FORCED, [], None, descr=faildescr),
- ResOperation(rop.FINISH, [i3, i4, i5, i6], None,
- descr=BasicFailDescr(0))
+ ResOperation(rop.GUARD_FALSE, [i3], None,
+ descr=BasicFailDescr(0)),
+ ResOperation(rop.FINISH, [], None,
+ descr=BasicFailDescr(1))
]
+ ops[-2].setfailargs([i3, i4, i5, i6])
ops[1].setfailargs([])
ops[3].setfailargs([])
ops[5].setfailargs([])
diff --git a/pypy/jit/codewriter/support.py b/pypy/jit/codewriter/support.py
--- a/pypy/jit/codewriter/support.py
+++ b/pypy/jit/codewriter/support.py
@@ -10,7 +10,7 @@
from pypy.rpython.extregistry import ExtRegistryEntry
from pypy.translator.simplify import get_funcobj
from pypy.translator.unsimplify import split_block
-from pypy.objspace.flow.model import Constant
+from pypy.objspace.flow.model import Variable, Constant
from pypy.translator.translator import TranslationContext
from pypy.annotation.policy import AnnotatorPolicy
from pypy.annotation import model as annmodel
@@ -59,6 +59,45 @@
rtyper = annotate(func, values)
return rtyper.annotator.translator.graphs[0]
+def autodetect_jit_markers_redvars(graph):
+ # the idea is to find all the jit_merge_point and
+ # add all the variables across the links to the reds.
+ for block, op in graph.iterblockops():
+ if op.opname == 'jit_marker':
+ jitdriver = op.args[1].value
+ if not jitdriver.autoreds:
+ continue
+ # if we want to support also can_enter_jit, we should find a
+ # way to detect a consistent set of red vars to pass *both* to
+ # jit_merge_point and can_enter_jit. The current simple
+ # solution doesn't work because can_enter_jit might be in
+ # another block, so the set of alive_v will be different.
+ methname = op.args[0].value
+ assert methname == 'jit_merge_point', (
+ "reds='auto' is supported only for jit drivers which "
+ "calls only jit_merge_point. Found a call to %s" % methname)
+ #
+ # compute the set of live variables across the jit_marker
+ alive_v = set()
+ for link in block.exits:
+ alive_v.update(link.args)
+ alive_v.difference_update(link.getextravars())
+ for op1 in block.operations[::-1]:
+ if op1 is op:
+ break # stop when the meet the jit_marker
+ alive_v.discard(op1.result)
+ alive_v.update(op1.args)
+ greens_v = op.args[2:]
+ reds_v = alive_v - set(greens_v)
+ reds_v = [v for v in reds_v if isinstance(v, Variable) and
+ v.concretetype is not lltype.Void]
+ reds_v = sort_vars(reds_v)
+ op.args.extend(reds_v)
+ if jitdriver.numreds is None:
+ jitdriver.numreds = len(reds_v)
+ else:
+ assert jitdriver.numreds == len(reds_v), 'inconsistent number of reds_v'
+
def split_before_jit_merge_point(graph, portalblock, portalopindex):
"""Split the block just before the 'jit_merge_point',
making sure the input args are in the canonical order.
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
@@ -357,6 +357,9 @@
def initarglist(self, args):
self._args = args
+ if not we_are_translated() and \
+ self.__class__.__name__.startswith('FINISH'): # XXX remove me
+ assert len(args) <= 1 # FINISH operations take 0 or 1 arg now
def getarglist(self):
return self._args
diff --git a/pypy/jit/metainterp/test/test_warmspot.py b/pypy/jit/metainterp/test/test_warmspot.py
--- a/pypy/jit/metainterp/test/test_warmspot.py
+++ b/pypy/jit/metainterp/test/test_warmspot.py
@@ -383,6 +383,23 @@
assert res == expected
self.check_resops(int_sub=2, int_mul=0, int_add=2)
+ def test_loop_automatic_reds_not_too_many_redvars(self):
+ myjitdriver = JitDriver(greens = ['m'], reds = 'auto')
+ def one():
+ return 1
+ def f(n, m):
+ res = 0
+ while n > 0:
+ n -= one()
+ myjitdriver.jit_merge_point(m=m)
+ res += m*2
+ return res
+ expected = f(21, 5)
+ res = self.meta_interp(f, [21, 5])
+ assert res == expected
+ oplabel = get_stats().loops[0].operations[0]
+ assert len(oplabel.getarglist()) == 2 # 'n', 'res' in some order
+
def test_inline_jit_merge_point(self):
# test that the machinery to inline jit_merge_points in callers
# works. The final user does not need to mess manually with the
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
@@ -347,49 +347,13 @@
self.jitdrivers_sd = []
graphs = self.translator.graphs
for graph, block, pos in find_jit_merge_points(graphs):
- self.autodetect_jit_markers_redvars(graph)
+ support.autodetect_jit_markers_redvars(graph)
self.split_graph_and_record_jitdriver(graph, block, pos)
#
assert (len(set([jd.jitdriver for jd in self.jitdrivers_sd])) ==
len(self.jitdrivers_sd)), \
"there are multiple jit_merge_points with the same jitdriver"
- def autodetect_jit_markers_redvars(self, graph):
- # the idea is to find all the jit_merge_point and can_enter_jit and
- # add all the variables across the links to the reds.
- for block, op in graph.iterblockops():
- if op.opname == 'jit_marker':
- jitdriver = op.args[1].value
- if not jitdriver.autoreds:
- continue
- # if we want to support also can_enter_jit, we should find a
- # way to detect a consistent set of red vars to pass *both* to
- # jit_merge_point and can_enter_jit. The current simple
- # solution doesn't work because can_enter_jit might be in
- # another block, so the set of alive_v will be different.
- methname = op.args[0].value
- assert methname == 'jit_merge_point', (
- "reds='auto' is supported only for jit drivers which "
- "calls only jit_merge_point. Found a call to %s" % methname)
- #
- # compute the set of live variables before the jit_marker
- alive_v = set(block.inputargs)
- for op1 in block.operations:
- if op1 is op:
- break # stop when the meet the jit_marker
- if op1.result.concretetype != lltype.Void:
- alive_v.add(op1.result)
- greens_v = op.args[2:]
- reds_v = alive_v - set(greens_v)
- reds_v = [v for v in reds_v if v.concretetype is not lltype.Void]
- reds_v = support.sort_vars(reds_v)
- op.args.extend(reds_v)
- if jitdriver.numreds is None:
- jitdriver.numreds = len(reds_v)
- else:
- assert jitdriver.numreds == len(reds_v), 'inconsistent number of reds_v'
-
-
def split_graph_and_record_jitdriver(self, graph, block, pos):
op = block.operations[pos]
jd = JitDriverStaticData()
@@ -717,6 +681,9 @@
jitdriver = op.args[1].value
assert jitdriver in sublists, \
"can_enter_jit with no matching jit_merge_point"
+ assert not jitdriver.autoreds, (
+ "can_enter_jit not supported with a jitdriver that "
+ "has reds='auto'")
jd, sublist = sublists[jitdriver]
origportalgraph = jd._jit_merge_point_in
if graph is not origportalgraph:
diff --git a/pypy/module/micronumpy/arrayimpl/concrete.py b/pypy/module/micronumpy/arrayimpl/concrete.py
--- a/pypy/module/micronumpy/arrayimpl/concrete.py
+++ b/pypy/module/micronumpy/arrayimpl/concrete.py
@@ -13,6 +13,7 @@
from pypy.rlib.debug import make_sure_not_resized
class ConcreteArrayIterator(base.BaseArrayIterator):
+ _immutable_fields_ = ['dtype', 'skip', 'size']
def __init__(self, array):
self.array = array
self.offset = 0
@@ -21,10 +22,10 @@
self.size = array.size
def setitem(self, elem):
- self.array.setitem(self.offset, elem)
+ self.dtype.setitem(self.array, self.offset, elem)
def getitem(self):
- return self.array.getitem(self.offset)
+ return self.dtype.getitem(self.array, self.offset)
def getitem_bool(self):
return self.dtype.getitem_bool(self.array, self.offset)
@@ -42,13 +43,16 @@
self.offset %= self.size
class OneDimViewIterator(ConcreteArrayIterator):
- def __init__(self, array):
+ ''' The view iterator dtype can be different from the
+ array.dtype, this is what makes it a View
+ '''
+ def __init__(self, array, dtype, start, strides, shape):
self.array = array
- self.offset = array.start
- self.skip = array.get_strides()[0]
- self.dtype = array.dtype
+ self.dtype = dtype
+ self.offset = start
+ self.skip = strides[0]
self.index = 0
- self.size = array.get_shape()[0]
+ self.size = shape[0]
def next(self):
self.offset += self.skip
@@ -65,9 +69,13 @@
self.offset %= self.size
class MultiDimViewIterator(ConcreteArrayIterator):
- def __init__(self, array, start, strides, backstrides, shape):
+ ''' The view iterator dtype can be different from the
+ array.dtype, this is what makes it a View
+ '''
+ def __init__(self, array, dtype, start, strides, backstrides, shape):
self.indexes = [0] * len(shape)
self.array = array
+ self.dtype = dtype
self.shape = shape
self.offset = start
self.shapelen = len(shape)
@@ -131,12 +139,13 @@
self.offset = array.start
self.dim = dim
self.array = array
+ self.dtype = array.dtype
def setitem(self, elem):
- self.array.setitem(self.offset, elem)
+ self.dtype.setitem(self.array, self.offset, elem)
def getitem(self):
- return self.array.getitem(self.offset)
+ return self.dtype.getitem(self.array, self.offset)
@jit.unroll_safe
def next(self):
@@ -220,6 +229,32 @@
new_shape, self)
else:
return None
+
+ def get_real(self):
+ strides = self.get_strides()
+ backstrides = self.get_backstrides()
+ if self.dtype.is_complex_type():
+ dtype = self.dtype.float_type
+ return SliceArray(self.start, strides, backstrides,
+ self.get_shape(), self, dtype=dtype)
+ return SliceArray(self.start, strides, backstrides,
+ self.get_shape(), self)
+
+ def get_imag(self):
+ strides = self.get_strides()
+ backstrides = self.get_backstrides()
+ if self.dtype.is_complex_type():
+ dtype = self.dtype.float_type
+ return SliceArray(self.start + dtype.get_size(), strides,
+ backstrides, self.get_shape(), self, dtype=dtype)
+ if self.dtype.is_flexible_type():
+ # numpy returns self for self.imag
+ return SliceArray(self.start, strides, backstrides,
+ self.get_shape(), self)
+ impl = NonWritableArray(self.get_shape(), self.dtype, self.order, strides,
+ backstrides)
+ impl.fill(self.dtype.box(0))
+ return impl
# -------------------- applevel get/setitem -----------------------
@@ -377,7 +412,7 @@
def create_dot_iter(self, shape, skip):
r = calculate_dot_strides(self.get_strides(), self.get_backstrides(),
shape, skip)
- return MultiDimViewIterator(self, self.start, r[0], r[1], shape)
+ return MultiDimViewIterator(self, self.dtype, self.start, r[0], r[1], shape)
def swapaxes(self, axis1, axis2):
shape = self.get_shape()[:]
@@ -411,7 +446,7 @@
r = calculate_broadcast_strides(self.get_strides(),
self.get_backstrides(),
self.get_shape(), shape)
- return MultiDimViewIterator(self, 0, r[0], r[1], shape)
+ return MultiDimViewIterator(self, self.dtype, 0, r[0], r[1], shape)
def fill(self, box):
self.dtype.fill(self.storage, box, 0, self.size)
@@ -424,6 +459,12 @@
self.order)
return SliceArray(0, strides, backstrides, new_shape, self)
+class NonWritableArray(ConcreteArray):
+ def descr_setitem(self, space, w_index, w_value):
+ raise OperationError(space.w_RuntimeError, space.wrap(
+ "array is not writable"))
+
+
class SliceArray(BaseConcreteArray):
def __init__(self, start, strides, backstrides, shape, parent, dtype=None):
self.strides = strides
@@ -448,11 +489,12 @@
r = calculate_broadcast_strides(self.get_strides(),
self.get_backstrides(),
self.get_shape(), shape)
- return MultiDimViewIterator(self.parent,
+ return MultiDimViewIterator(self.parent, self.dtype,
self.start, r[0], r[1], shape)
if len(self.get_shape()) == 1:
- return OneDimViewIterator(self)
- return MultiDimViewIterator(self.parent, self.start,
+ return OneDimViewIterator(self.parent, self.dtype, self.start,
+ self.get_strides(), self.get_shape())
+ return MultiDimViewIterator(self.parent, self.dtype, self.start,
self.get_strides(),
self.get_backstrides(), self.get_shape())
diff --git a/pypy/module/micronumpy/interp_dtype.py b/pypy/module/micronumpy/interp_dtype.py
--- a/pypy/module/micronumpy/interp_dtype.py
+++ b/pypy/module/micronumpy/interp_dtype.py
@@ -136,7 +136,7 @@
return self.kind == SIGNEDLTR
def is_complex_type(self):
- return (self.num == 14 or self.num == 15 or self.num == 16)
+ return False
def is_bool_type(self):
return self.kind == BOOLLTR
@@ -155,6 +155,19 @@
def get_size(self):
return self.itemtype.get_element_size()
+class W_ComplexDtype(W_Dtype):
+
+ def __init__(self, itemtype, num, kind, name, char, w_box_type,
+ alternate_constructors=[], aliases=[],
+ fields=None, fieldnames=None, native=True, float_type=None):
+ W_Dtype.__init__(self, itemtype, num, kind, name, char, w_box_type,
+ alternate_constructors=alternate_constructors, aliases=aliases,
+ fields=fields, fieldnames=fieldnames, native=native)
+ self.float_type = float_type
+
+ def is_complex_type(self):
+ return True
+
def dtype_from_list(space, w_lst):
lst_w = space.listview(w_lst)
fields = {}
@@ -413,15 +426,16 @@
alternate_constructors=[space.w_float],
aliases=["float"],
)
- self.w_complex64dtype = W_Dtype(
+ self.w_complex64dtype = W_ComplexDtype(
types.Complex64(),
num=14,
kind=COMPLEXLTR,
name="complex64",
char="F",
w_box_type = space.gettypefor(interp_boxes.W_Complex64Box),
+ float_type = self.w_float32dtype,
)
- self.w_complex128dtype = W_Dtype(
+ self.w_complex128dtype = W_ComplexDtype(
types.Complex128(),
num=15,
kind=COMPLEXLTR,
@@ -430,6 +444,7 @@
w_box_type = space.gettypefor(interp_boxes.W_Complex128Box),
alternate_constructors=[space.w_complex],
aliases=["complex"],
+ float_type = self.w_float64dtype,
)
if interp_boxes.long_double_size == 12:
self.w_float96dtype = W_Dtype(
@@ -443,7 +458,7 @@
)
self.w_longdouble = self.w_float96dtype
- self.w_complex192dtype = W_Dtype(
+ self.w_complex192dtype = W_ComplexDtype(
types.Complex192(),
num=16,
kind=COMPLEXLTR,
@@ -452,6 +467,7 @@
w_box_type = space.gettypefor(interp_boxes.W_Complex192Box),
alternate_constructors=[space.w_complex],
aliases=["clongdouble", "clongfloat"],
+ float_type = self.w_float96dtype,
)
self.w_clongdouble = self.w_complex192dtype
@@ -467,7 +483,7 @@
)
self.w_longdouble = self.w_float128dtype
- self.w_complex256dtype = W_Dtype(
+ self.w_complex256dtype = W_ComplexDtype(
types.Complex256(),
num=16,
kind=COMPLEXLTR,
@@ -476,6 +492,7 @@
w_box_type = space.gettypefor(interp_boxes.W_Complex256Box),
alternate_constructors=[space.w_complex],
aliases=["clongdouble", "clongfloat"],
+ float_type = self.w_float128dtype,
)
self.w_clongdouble = self.w_complex256dtype
else:
diff --git a/pypy/module/micronumpy/interp_numarray.py b/pypy/module/micronumpy/interp_numarray.py
--- a/pypy/module/micronumpy/interp_numarray.py
+++ b/pypy/module/micronumpy/interp_numarray.py
@@ -235,6 +235,29 @@
def descr_copy(self, space):
return W_NDimArray(self.implementation.copy())
+ def descr_get_real(self, space):
+ return W_NDimArray(self.implementation.get_real())
+
+ def descr_get_imag(self, space):
+ ret = self.implementation.get_imag()
+ if ret:
+ return W_NDimArray(ret)
+ raise OperationError(space.w_NotImplementedError,
+ space.wrap('imag not implemented for this dtype'))
+
+ def descr_set_real(self, space, w_value):
+ # copy (broadcast) values into self
+ tmp = self.implementation.get_real()
+ tmp.setslice(space, convert_to_array(space, w_value))
+
+ def descr_set_imag(self, space, w_value):
+ # if possible, copy (broadcast) values into self
+ if not self.get_dtype().is_complex_type():
+ raise OperationError(space.w_TypeError,
+ space.wrap('array does not have imaginary part to set'))
+ tmp = self.implementation.get_imag()
+ tmp.setslice(space, convert_to_array(space, w_value))
+
def descr_reshape(self, space, args_w):
"""reshape(...)
a.reshape(shape)
@@ -387,8 +410,6 @@
descr_neg = _unaryop_impl("negative")
descr_abs = _unaryop_impl("absolute")
descr_invert = _unaryop_impl("invert")
- descr_get_real = _unaryop_impl("real")
- descr_get_imag = _unaryop_impl("imag")
def descr_nonzero(self, space):
if self.get_size() > 1:
@@ -635,9 +656,10 @@
swapaxes = interp2app(W_NDimArray.descr_swapaxes),
flat = GetSetProperty(W_NDimArray.descr_get_flatiter),
item = interp2app(W_NDimArray.descr_item),
- real = GetSetProperty(W_NDimArray.descr_get_real),
- imag = GetSetProperty(W_NDimArray.descr_get_imag),
-
+ real = GetSetProperty(W_NDimArray.descr_get_real,
+ W_NDimArray.descr_set_real),
+ imag = GetSetProperty(W_NDimArray.descr_get_imag,
+ W_NDimArray.descr_set_imag),
__array_interface__ = GetSetProperty(W_NDimArray.descr_array_iface),
)
diff --git a/pypy/module/micronumpy/test/test_iter.py b/pypy/module/micronumpy/test/test_iter.py
--- a/pypy/module/micronumpy/test/test_iter.py
+++ b/pypy/module/micronumpy/test/test_iter.py
@@ -12,7 +12,7 @@
strides = [5, 1]
backstrides = [x * (y - 1) for x,y in zip(strides, shape)]
assert backstrides == [10, 4]
- i = MultiDimViewIterator(MockArray, start, strides, backstrides, shape)
+ i = MultiDimViewIterator(MockArray, None, start, strides, backstrides, shape)
i.next()
i.next()
i.next()
@@ -30,7 +30,7 @@
strides = [1, 3]
backstrides = [x * (y - 1) for x,y in zip(strides, shape)]
assert backstrides == [2, 12]
- i = MultiDimViewIterator(MockArray, start, strides, backstrides, shape)
+ i = MultiDimViewIterator(MockArray, None, start, strides, backstrides, shape)
i.next()
i.next()
i.next()
@@ -51,7 +51,7 @@
strides = [5, 1]
backstrides = [x * (y - 1) for x,y in zip(strides, shape)]
assert backstrides == [10, 4]
- i = MultiDimViewIterator(MockArray, start, strides, backstrides, shape)
+ i = MultiDimViewIterator(MockArray, None, start, strides, backstrides, shape)
i.next_skip_x(2)
i.next_skip_x(2)
i.next_skip_x(2)
@@ -74,7 +74,7 @@
strides = [1, 3]
backstrides = [x * (y - 1) for x,y in zip(strides, shape)]
assert backstrides == [2, 12]
- i = MultiDimViewIterator(MockArray, start, strides, backstrides, shape)
+ i = MultiDimViewIterator(MockArray, None, start, strides, backstrides, shape)
i.next_skip_x(2)
i.next_skip_x(2)
i.next_skip_x(2)
diff --git a/pypy/module/micronumpy/test/test_numarray.py b/pypy/module/micronumpy/test/test_numarray.py
--- a/pypy/module/micronumpy/test/test_numarray.py
+++ b/pypy/module/micronumpy/test/test_numarray.py
@@ -1169,8 +1169,8 @@
assert (d == [[1, 0, 0], [0, 1, 0], [0, 0, 1]]).all()
def test_eye(self):
- from _numpypy import eye, array
- from _numpypy import int32, float64, dtype
+ from _numpypy import eye
+ from _numpypy import int32, dtype
a = eye(0)
assert len(a) == 0
assert a.dtype == dtype('float64')
@@ -1345,6 +1345,42 @@
assert b[0] == 3
assert b[1] == 2
+ def test_realimag_views(self):
+ from _numpypy import arange, array
+ a = arange(15)
+ b = a.real
+ b[5]=50
+ assert a[5] == 50
+ b = a.imag
+ assert b[7] == 0
+ raises(RuntimeError, 'b[7] = -2')
+ raises(TypeError, 'a.imag = -2')
+ a = array(['abc','def'],dtype='S3')
+ b = a.real
+ assert a[0] == b[0]
+ assert a[1] == b[1]
+ b[1] = 'xyz'
+ assert a[1] == 'xyz'
+ assert a.imag[0] == 'abc'
+ raises(TypeError, 'a.imag = "qop"')
+ a=array([[1+1j, 2-3j, 4+5j],[-6+7j, 8-9j, -2-1j]])
+ assert a.real[0,1] == 2
+ a.real[0,1] = -20
+ assert a[0,1].real == -20
+ b = a.imag
+ assert b[1,2] == -1
+ b[1,2] = 30
+ assert a[1,2].imag == 30
+ a.real = 13
+ assert a[1,1].real == 13
+ a=array([1+1j, 2-3j, 4+5j, -6+7j, 8-9j, -2-1j])
+ a.real = 13
+ assert a[3].real == 13
+ a.imag = -5
+ a.imag[3] = -10
+ assert a[3].imag == -10
+ assert a[2].imag == -5
+
def test_tolist_scalar(self):
from _numpypy import int32, bool_
x = int32(23)
@@ -2273,7 +2309,7 @@
assert a[0]['x'] == 'a'
def test_stringarray(self):
- from _numpypy import array, flexible
+ from _numpypy import array
a = array(['abc'],'S3')
assert str(a.dtype) == '|S3'
a = array(['abc'])
@@ -2293,7 +2329,6 @@
def test_flexible_repr(self):
# import overrides str(), repr() for array
- from numpypy.core import arrayprint
from _numpypy import array
a = array(['abc'],'S3')
s = repr(a)
diff --git a/pypy/objspace/flow/test/test_objspace.py b/pypy/objspace/flow/test/test_objspace.py
--- a/pypy/objspace/flow/test/test_objspace.py
+++ b/pypy/objspace/flow/test/test_objspace.py
@@ -8,18 +8,17 @@
from pypy.objspace.flow.objspace import FlowObjSpace
from pypy.objspace.flow.flowcontext import FlowingError, FlowSpaceFrame
from pypy import conftest
-from pypy.tool.stdlib_opcode import bytecode_spec, host_bytecode_spec
+from pypy.tool.stdlib_opcode import host_bytecode_spec
import os
import operator
is_operator = getattr(operator, 'is_', operator.eq) # it's not there 2.2
@contextmanager
-def patching_opcodes(*opcodes):
+def patching_opcodes(**opcodes):
meth_names = host_bytecode_spec.method_names
- opnums = [bytecode_spec.opmap[name] for name in opcodes]
old_name = {}
- for name, num in zip(opcodes, opnums):
+ for name, num in opcodes.items():
old_name[num] = meth_names[num]
meth_names[num] = name
yield
@@ -898,7 +897,7 @@
""" Tests code generated by pypy-c compiled with CALL_METHOD
bytecode
"""
- with patching_opcodes('CALL_METHOD', 'LOOKUP_METHOD'):
+ with patching_opcodes(CALL_METHOD=202, LOOKUP_METHOD=201):
class X:
def m(self):
return 3
@@ -922,7 +921,7 @@
""" Tests code generated by pypy-c compiled with BUILD_LIST_FROM_ARG
bytecode
"""
- with patching_opcodes('BUILD_LIST_FROM_ARG'):
+ with patching_opcodes(BUILD_LIST_FROM_ARG=203):
def f():
return [i for i in "abc"]
diff --git a/pypy/rpython/lltypesystem/rffi.py b/pypy/rpython/lltypesystem/rffi.py
--- a/pypy/rpython/lltypesystem/rffi.py
+++ b/pypy/rpython/lltypesystem/rffi.py
@@ -2,12 +2,12 @@
from pypy.annotation import model as annmodel
from pypy.rpython.lltypesystem import lltype, rstr
from pypy.rpython.lltypesystem import ll2ctypes
-from pypy.rpython.lltypesystem.llmemory import cast_adr_to_ptr, cast_ptr_to_adr
+from pypy.rpython.lltypesystem.llmemory import cast_ptr_to_adr
from pypy.rpython.lltypesystem.llmemory import itemoffsetof, raw_memcopy
from pypy.annotation.model import lltype_to_annotation
from pypy.tool.sourcetools import func_with_new_name
-from pypy.rlib.objectmodel import Symbolic, CDefinedIntSymbolic
-from pypy.rlib.objectmodel import keepalive_until_here
+from pypy.rlib.objectmodel import Symbolic
+from pypy.rlib.objectmodel import keepalive_until_here, enforceargs
from pypy.rlib import rarithmetic, rgc
from pypy.rpython.extregistry import ExtRegistryEntry
from pypy.rlib.unroll import unrolling_iterable
@@ -795,6 +795,7 @@
# (char*, str, int, int) -> None
@jit.dont_look_inside
+ @enforceargs(None, None, int, int)
def str_from_buffer(raw_buf, gc_buf, allocated_size, needed_size):
"""
Converts from a pair returned by alloc_buffer to a high-level string.
@@ -833,6 +834,7 @@
lltype.free(raw_buf, flavor='raw')
# char* -> str, with an upper bound on the length in case there is no \x00
+ @enforceargs(None, int)
def charp2strn(cp, maxlen):
b = builder_class(maxlen)
i = 0
diff --git a/pypy/translator/driver.py b/pypy/translator/driver.py
--- a/pypy/translator/driver.py
+++ b/pypy/translator/driver.py
@@ -362,7 +362,7 @@
@taskdef([RTYPE], "JIT compiler generation")
def task_pyjitpl_lltype(self):
""" Generate bytecodes for JIT and flow the JIT helper functions
- ootype version
+ lltype version
"""
get_policy = self.extra['jitpolicy']
self.jitpolicy = get_policy(self)
More information about the pypy-commit
mailing list