Author: Maciej Fijalkowski <fij...@gmail.com> Branch: Changeset: r59984:092d0cd721de Date: 2013-01-12 11:31 +0200 http://bitbucket.org/pypy/pypy/changeset/092d0cd721de/
Log: merge 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 @@ -1192,7 +1192,8 @@ values.append(longlong.getfloatstorage(r.random())) # looptoken = JitCellToken() - faildescr = BasicFailDescr(42) + guarddescr = BasicFailDescr(42) + faildescr = BasicFailDescr(43) operations = [] retboxes = [] retvalues = [] @@ -1221,9 +1222,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 @@ -1344,12 +1349,15 @@ targettoken = TargetToken() faildescr1 = BasicFailDescr(1) faildescr2 = BasicFailDescr(2) + faildescr3 = BasicFailDescr(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) @@ -1382,6 +1390,7 @@ py.test.skip("requires floats") fboxes = [BoxFloat() for i in range(3)] faildescr1 = BasicFailDescr(100) + faildescr2 = BasicFailDescr(102) loopops = """ [i0,f1, f2] f3 = float_add(f1, f2) @@ -1406,9 +1415,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, @@ -2002,7 +2015,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) @@ -2023,8 +2036,7 @@ looptoken = JitCellToken() self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) deadframe = self.cpu.execute_token(looptoken, 1) - assert self.cpu.get_latest_value_int(deadframe, 0) == 0 - assert self.cpu.get_latest_value_ref(deadframe, 1) == xptr + assert self.cpu.get_latest_value_ref(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 @@ -353,6 +353,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: _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit