Author: Carl Friedrich Bolz <cfb...@gmx.de> Branch: Changeset: r50060:0c65719691d8 Date: 2011-12-02 12:10 +0100 http://bitbucket.org/pypy/pypy/changeset/0c65719691d8/
Log: merge diff --git a/pypy/doc/index.rst b/pypy/doc/index.rst --- a/pypy/doc/index.rst +++ b/pypy/doc/index.rst @@ -15,7 +15,7 @@ * `FAQ`_: some frequently asked questions. -* `Release 1.6`_: the latest official release +* `Release 1.7`_: the latest official release * `PyPy Blog`_: news and status info about PyPy @@ -75,7 +75,7 @@ .. _`Getting Started`: getting-started.html .. _`Papers`: extradoc.html .. _`Videos`: video-index.html -.. _`Release 1.6`: http://pypy.org/download.html +.. _`Release 1.7`: http://pypy.org/download.html .. _`speed.pypy.org`: http://speed.pypy.org .. _`RPython toolchain`: translation.html .. _`potential project ideas`: project-ideas.html @@ -120,9 +120,9 @@ Windows, on top of .NET, and on top of Java. To dig into PyPy it is recommended to try out the current Mercurial default branch, which is always working or mostly working, -instead of the latest release, which is `1.6`__. +instead of the latest release, which is `1.7`__. -.. __: release-1.6.0.html +.. __: release-1.7.0.html PyPy is mainly developed on Linux and Mac OS X. Windows is supported, but platform-specific bugs tend to take longer before we notice and fix diff --git a/pypy/jit/backend/llsupport/test/test_regalloc.py b/pypy/jit/backend/llsupport/test/test_regalloc.py --- a/pypy/jit/backend/llsupport/test/test_regalloc.py +++ b/pypy/jit/backend/llsupport/test/test_regalloc.py @@ -2,6 +2,8 @@ from pypy.jit.metainterp.history import BoxInt, ConstInt, BoxFloat, INT, FLOAT from pypy.jit.backend.llsupport.regalloc import FrameManager from pypy.jit.backend.llsupport.regalloc import RegisterManager as BaseRegMan +from pypy.jit.tool.oparser import parse +from pypy.jit.backend.detect_cpu import getcpuclass def newboxes(*values): return [BoxInt(v) for v in values] diff --git a/pypy/jit/backend/x86/regalloc.py b/pypy/jit/backend/x86/regalloc.py --- a/pypy/jit/backend/x86/regalloc.py +++ b/pypy/jit/backend/x86/regalloc.py @@ -167,26 +167,22 @@ operations = cpu.gc_ll_descr.rewrite_assembler(cpu, operations, allgcrefs) # compute longevity of variables - longevity = self._compute_vars_longevity(inputargs, operations) + longevity, useful = self._compute_vars_longevity(inputargs, operations) self.longevity = longevity self.rm = gpr_reg_mgr_cls(longevity, frame_manager = self.fm, assembler = self.assembler) self.xrm = xmm_reg_mgr_cls(longevity, frame_manager = self.fm, assembler = self.assembler) - return operations + return operations, useful def prepare_loop(self, inputargs, operations, looptoken, allgcrefs): - operations = self._prepare(inputargs, operations, allgcrefs) - jump = operations[-1] - loop_consts = self._compute_loop_consts(inputargs, jump, looptoken) - self.loop_consts = loop_consts - return self._process_inputargs(inputargs), operations + operations, useful = self._prepare(inputargs, operations, allgcrefs) + return self._process_inputargs(inputargs, useful), operations def prepare_bridge(self, prev_depths, inputargs, arglocs, operations, allgcrefs): - operations = self._prepare(inputargs, operations, allgcrefs) - self.loop_consts = {} + operations, _ = self._prepare(inputargs, operations, allgcrefs) self._update_bindings(arglocs, inputargs) self.fm.frame_depth = prev_depths[0] self.param_depth = prev_depths[1] @@ -195,7 +191,7 @@ def reserve_param(self, n): self.param_depth = max(self.param_depth, n) - def _process_inputargs(self, inputargs): + def _process_inputargs(self, inputargs, useful): # XXX we can sort out here by longevity if we need something # more optimal floatlocs = [None] * len(inputargs) @@ -211,7 +207,7 @@ arg = inputargs[i] assert not isinstance(arg, Const) reg = None - if arg not in self.loop_consts and self.longevity[arg][1] > -1: + if self.longevity[arg][1] > -1 and arg in useful: if arg.type == FLOAT: # xxx is it really a good idea? at the first CALL they # will all be flushed anyway @@ -287,15 +283,15 @@ else: return self.xrm.make_sure_var_in_reg(var, forbidden_vars) - def _compute_loop_consts(self, inputargs, jump, looptoken): - if jump.getopnum() != rop.JUMP or jump.getdescr() is not looptoken: - loop_consts = {} - else: - loop_consts = {} - for i in range(len(inputargs)): - if inputargs[i] is jump.getarg(i): - loop_consts[inputargs[i]] = i - return loop_consts + #def _compute_loop_consts(self, inputargs, jump, looptoken): + # if jump.getopnum() != rop.JUMP or jump.getdescr() is not looptoken: + # loop_consts = {} + # else: + # loop_consts = {} + # for i in range(len(inputargs)): + # if inputargs[i] is jump.getarg(i): + # loop_consts[inputargs[i]] = i + # return loop_consts def _update_bindings(self, locs, inputargs): # XXX this should probably go to llsupport/regalloc.py @@ -450,8 +446,14 @@ def _compute_vars_longevity(self, inputargs, operations): # compute a dictionary that maps variables to index in # operations that is a "last-time-seen" + + # returns a pair longevity/useful. Non-useful variables are ones that + # never appear in the assembler or it does not matter if they appear on + # stack or in registers. Main example is loop arguments that go + # only to guard operations or to jump or to finish produced = {} last_used = {} + useful = {} for i in range(len(operations)-1, -1, -1): op = operations[i] if op.result: @@ -459,8 +461,11 @@ continue assert op.result not in produced produced[op.result] = i + opnum = op.getopnum() for j in range(op.numargs()): arg = op.getarg(j) + if opnum != rop.JUMP and opnum != rop.FINISH: + useful[arg] = None if isinstance(arg, Box) and arg not in last_used: last_used[arg] = i if op.is_guard(): @@ -486,7 +491,7 @@ longevity[arg] = (0, last_used[arg]) del last_used[arg] assert len(last_used) == 0 - return longevity + return longevity, useful def loc(self, v): if v is None: # xxx kludgy 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 @@ -149,6 +149,13 @@ self.cpu.execute_token(loop.token) return loop + def prepare_loop(self, ops): + loop = self.parse(ops) + regalloc = RegAlloc(self.cpu.assembler, False) + regalloc.prepare_loop(loop.inputargs, loop.operations, + loop.token, []) + return regalloc + def getint(self, index): return self.cpu.get_latest_value_int(index) @@ -422,6 +429,35 @@ self.run(loop) assert self.getints(9) == range(9) + def test_loopargs(self): + ops = """ + [i0, i1, i2, i3] + i4 = int_add(i0, i1) + jump(i4, i1, i2, i3) + """ + regalloc = self.prepare_loop(ops) + assert len(regalloc.rm.reg_bindings) == 2 + + def test_loopargs_2(self): + ops = """ + [i0, i1, i2, i3] + i4 = int_add(i0, i1) + finish(i4, i1, i2, i3) + """ + regalloc = self.prepare_loop(ops) + assert len(regalloc.rm.reg_bindings) == 2 + + def test_loopargs_3(self): + ops = """ + [i0, i1, i2, i3] + i4 = int_add(i0, i1) + guard_true(i4) [i0, i1, i2, i3, i4] + jump(i4, i1, i2, i3) + """ + regalloc = self.prepare_loop(ops) + assert len(regalloc.rm.reg_bindings) == 2 + + class TestRegallocCompOps(BaseTestRegalloc): def test_cmp_op_0(self): diff --git a/pypy/jit/metainterp/optimizeopt/rewrite.py b/pypy/jit/metainterp/optimizeopt/rewrite.py --- a/pypy/jit/metainterp/optimizeopt/rewrite.py +++ b/pypy/jit/metainterp/optimizeopt/rewrite.py @@ -491,6 +491,9 @@ self.pure(rop.CAST_PTR_TO_INT, [op.result], op.getarg(0)) self.emit_operation(op) + def optimize_SAME_AS(self, op): + self.make_equal_to(op.result, self.getvalue(op.getarg(0))) + dispatch_opt = make_dispatcher_method(OptRewrite, 'optimize_', default=OptRewrite.emit_operation) optimize_guards = _findall(OptRewrite, 'optimize_', 'GUARD') diff --git a/pypy/jit/metainterp/test/test_virtual.py b/pypy/jit/metainterp/test/test_virtual.py --- a/pypy/jit/metainterp/test/test_virtual.py +++ b/pypy/jit/metainterp/test/test_virtual.py @@ -612,7 +612,7 @@ return node.value res = self.meta_interp(f, [48, 3], policy=StopAtXPolicy(externfn)) assert res == f(48, 3) - self.check_loop_count(3) + self.check_loop_count(5) res = self.meta_interp(f, [40, 3], policy=StopAtXPolicy(externfn)) assert res == f(40, 3) self.check_loop_count(3) @@ -761,6 +761,27 @@ res = self.meta_interp(f, [0x1F, 0x11]) assert res == f(0x1F, 0x11) + def test_duplicated_virtual(self): + myjitdriver = JitDriver(greens = [], reds = ['n', 'node1', 'node2']) + def f(n): + node1 = self._new() + node1.value = 0 + node2 = self._new() + node2.value = 1 + while n > 0: + myjitdriver.jit_merge_point(n=n, node1=node1, node2=node2) + next = self._new() + next.value = node1.value + node2.value + n + node1 = next + node2 = next + n -= 1 + return node1.value + res = self.meta_interp(f, [10]) + assert res == f(10) + self.check_resops(new_with_vtable=0, new=0) + + + class VirtualMiscTests: def test_multiple_equal_virtuals(self): diff --git a/pypy/module/__pypy__/interp_magic.py b/pypy/module/__pypy__/interp_magic.py --- a/pypy/module/__pypy__/interp_magic.py +++ b/pypy/module/__pypy__/interp_magic.py @@ -75,7 +75,8 @@ def list_strategy(space, w_list): from pypy.objspace.std.listobject import W_ListObject - str_type = None if isinstance(w_list, W_ListObject): - str_type = w_list.strategy._applevel_repr - return space.wrap(str_type) + return space.wrap(w_list.strategy._applevel_repr) + else: + w_msg = space.wrap("Can only get the list strategy of a list") + raise OperationError(space.w_TypeError, w_msg) diff --git a/pypy/module/__pypy__/test/test_special.py b/pypy/module/__pypy__/test/test_special.py --- a/pypy/module/__pypy__/test/test_special.py +++ b/pypy/module/__pypy__/test/test_special.py @@ -57,17 +57,18 @@ def test_list_strategy(self): from __pypy__ import list_strategy - l = [1,2,3] + + l = [1, 2, 3] assert list_strategy(l) == "int" - l = ["a","b","c"] + l = ["a", "b", "c"] assert list_strategy(l) == "str" - l = [1.1,2.2,3.3] + l = [1.1, 2.2, 3.3] assert list_strategy(l) == "float" l = range(3) assert list_strategy(l) == "range" - l = [1,"b",3] + l = [1, "b", 3] assert list_strategy(l) == "object" l = [] assert list_strategy(l) == "empty" o = 5 - assert list_strategy(o) == None + raises(TypeError, list_strategy, 5) _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit