[pypy-svn] r52558 - in pypy/branch/jit-hotpath/pypy: jit/hintannotator jit/rainbow jit/rainbow/test rlib
arigo at codespeak.net
arigo at codespeak.net
Sat Mar 15 16:47:56 CET 2008
Author: arigo
Date: Sat Mar 15 16:47:55 2008
New Revision: 52558
Modified:
pypy/branch/jit-hotpath/pypy/jit/hintannotator/hotpath.py
pypy/branch/jit-hotpath/pypy/jit/rainbow/codewriter.py
pypy/branch/jit-hotpath/pypy/jit/rainbow/test/test_hotpath.py
pypy/branch/jit-hotpath/pypy/jit/rainbow/test/test_hp_promotion.py
pypy/branch/jit-hotpath/pypy/rlib/jit.py
Log:
Handle void variables across the jit_merge_point().
Modified: pypy/branch/jit-hotpath/pypy/jit/hintannotator/hotpath.py
==============================================================================
--- pypy/branch/jit-hotpath/pypy/jit/hintannotator/hotpath.py (original)
+++ pypy/branch/jit-hotpath/pypy/jit/hintannotator/hotpath.py Sat Mar 15 16:47:55 2008
@@ -1,4 +1,4 @@
-from pypy.objspace.flow.model import checkgraph, copygraph
+from pypy.objspace.flow.model import checkgraph, copygraph, Constant
from pypy.objspace.flow.model import Block, Link, SpaceOperation, Variable
from pypy.translator.unsimplify import split_block, varoftype
from pypy.translator.simplify import join_blocks
@@ -6,6 +6,7 @@
from pypy.jit.hintannotator.model import SomeLLAbstractConstant, OriginFlags
from pypy.annotation import model as annmodel
from pypy.rpython.rtyper import LowLevelOpList
+from pypy.rpython.lltypesystem import lltype
from pypy.rlib.jit import JitHintError
@@ -94,12 +95,14 @@
portalopindex = portalblock.operations.index(portalop)
# split the block just before the jit_merge_point()
if portalopindex > 0:
- split_block(hannotator, portalblock, portalopindex)
+ link = split_block(hannotator, portalblock, portalopindex)
+ portalblock = link.target
+ portalop = portalblock.operations[0]
# split again, this time enforcing the order of the live vars
# specified by the user in the jit_merge_point() call
- _, portalblock, portalop = find_jit_merge_point(graph)
- assert portalop is portalblock.operations[0]
- livevars = portalop.args[1:]
+ assert portalop.opname == 'jit_merge_point'
+ livevars = [v for v in portalop.args[1:]
+ if v.concretetype is not lltype.Void]
link = split_block(hannotator, portalblock, 0, livevars)
return link.target
else:
@@ -109,17 +112,30 @@
vars = [varoftype(v.concretetype, name=v) for v in graph.getargs()]
newblock = Block(vars)
+ op = graph.startblock.operations[0]
+ assert op.opname == 'jit_merge_point'
+ assert op.args[0].value is drivercls
+ allvars = []
+ i = 0
+ for v in op.args[1:]:
+ if v.concretetype is lltype.Void:
+ allvars.append(Constant(None, concretetype=lltype.Void))
+ else:
+ allvars.append(vars[i])
+ i += 1
+ assert i == len(vars)
+
llops = LowLevelOpList(rtyper)
# generate ops to make an instance of DriverCls
classdef = rtyper.annotator.bookkeeper.getuniqueclassdef(drivercls)
s_instance = annmodel.SomeInstance(classdef)
r_instance = rtyper.getrepr(s_instance)
v_self = r_instance.new_instance(llops)
- # generate ops to store the 'reds' variables on 'self'
+ # generate ops to store the 'greens' and 'reds' variables on 'self'
num_greens = len(drivercls.greens)
num_reds = len(drivercls.reds)
- assert len(vars) == num_greens + num_reds
- for name, v_value in zip(drivercls.reds, vars[num_greens:]):
+ assert len(allvars) == num_greens + num_reds
+ for name, v_value in zip(drivercls.greens + drivercls.reds, allvars):
r_instance.setfield(v_self, name, v_value, llops)
# generate a call to on_enter_jit(self)
on_enter_jit_func = drivercls.on_enter_jit.im_func
@@ -128,10 +144,13 @@
c_func = r_func.get_unique_llfn()
llops.genop('direct_call', [c_func, v_self])
# generate ops to reload the 'reds' variables from 'self'
- newvars = vars[:num_greens]
- for name, v_value in zip(drivercls.reds, vars[num_greens:]):
+ # XXX Warning! the 'greens' variables are not reloaded. This is
+ # a bit of a mess color-wise, and probably not useful.
+ newvars = allvars[:num_greens]
+ for name, v_value in zip(drivercls.reds, allvars[num_greens:]):
v_value = r_instance.getfield(v_self, name, llops)
newvars.append(v_value)
+ newvars = [v for v in newvars if v.concretetype is not lltype.Void]
# done, fill the block and link it to make it the startblock
newblock.operations[:] = llops
newblock.closeblock(Link(newvars, graph.startblock))
Modified: pypy/branch/jit-hotpath/pypy/jit/rainbow/codewriter.py
==============================================================================
--- pypy/branch/jit-hotpath/pypy/jit/rainbow/codewriter.py (original)
+++ pypy/branch/jit-hotpath/pypy/jit/rainbow/codewriter.py Sat Mar 15 16:47:55 2008
@@ -1378,14 +1378,15 @@
return c
def decode_hp_hint_args(self, op):
- # Returns (list-of-green-vars, list-of-red-vars).
+ # Returns (list-of-green-vars, list-of-red-vars) without Voids.
drivercls = op.args[0].value
numgreens = len(drivercls.greens)
numreds = len(drivercls.reds)
greens_v = op.args[1:1+numgreens]
reds_v = op.args[1+numgreens:]
assert len(reds_v) == numreds
- return greens_v, reds_v
+ return ([v for v in greens_v if v.concretetype is not lltype.Void],
+ [v for v in reds_v if v.concretetype is not lltype.Void])
def check_hp_hint_args(self, op):
# Check the colors of the jit_merge_point() and can_enter_jit()
Modified: pypy/branch/jit-hotpath/pypy/jit/rainbow/test/test_hotpath.py
==============================================================================
--- pypy/branch/jit-hotpath/pypy/jit/rainbow/test/test_hotpath.py (original)
+++ pypy/branch/jit-hotpath/pypy/jit/rainbow/test/test_hotpath.py Sat Mar 15 16:47:55 2008
@@ -352,6 +352,29 @@
"run_machine_code 2",
])
+ def test_on_enter_jit_many_vars(self):
+ class MyJitDriver(JitDriver):
+ greens = ['void1', 'm']
+ reds = ['void2', 'n']
+ def on_enter_jit(self):
+ self.n += self.m # doesn't make sense, just for testing
+ # note that the green 'self.m' cannot be modified
+ # (changes would not be reloaded into the 'm' var currently)
+
+ def ll_function(n, m):
+ MyJitDriver.jit_merge_point(n=n, m=m, void1=None, void2=None)
+ MyJitDriver.can_enter_jit(n=n, m=m, void1=None, void2=None)
+ hint(m, concrete=True)
+ return n + 5
+
+ res = self.run(ll_function, [2, 200], threshold=1, small=True)
+ assert res == 207
+ self.check_traces([
+ "jit_compile 200",
+ "done at hp_return",
+ "run_machine_code 200 2",
+ ])
+
def test_hp_tlr(self):
from pypy.jit.tl import tlr
Modified: pypy/branch/jit-hotpath/pypy/jit/rainbow/test/test_hp_promotion.py
==============================================================================
--- pypy/branch/jit-hotpath/pypy/jit/rainbow/test/test_hp_promotion.py (original)
+++ pypy/branch/jit-hotpath/pypy/jit/rainbow/test/test_hp_promotion.py Sat Mar 15 16:47:55 2008
@@ -258,6 +258,9 @@
self.check_insns(int_add=0, int_mul=0)
def test_more_promotes(self):
+ class MyJitDriver(JitDriver):
+ greens = []
+ reds = ['n', 'm', 'i', 's']
S = lltype.GcStruct('S', ('x', lltype.Signed), ('y', lltype.Signed))
def ll_two(s, i, m):
if i > 4:
@@ -279,7 +282,8 @@
s.y = 0
i = 0
while i < n:
- hint(None, global_merge_point=True)
+ MyJitDriver.jit_merge_point(n=n, m=m, i=i, s=s)
+ MyJitDriver.can_enter_jit(n=n, m=m, i=i, s=s)
k = ll_two(s, i, m)
if m & 1:
k *= 3
@@ -290,7 +294,7 @@
i += j
return s.x + s.y * 17
- res = self.interpret(ll_function, [100, 2])
+ res = self.run(ll_function, [100, 2], threshold=3)
assert res == ll_function(100, 2)
def test_mixed_merges(self):
@@ -323,22 +327,30 @@
assert res == ll_function(6, 3, 2, 2)
def test_green_across_global_mp(self):
- py.test.skip("void vars not handled correctly")
+ class MyJitDriver(JitDriver):
+ greens = ['n1', 'n2']
+ reds = ['total', 'n3', 'n4']
def ll_function(n1, n2, n3, n4, total):
while n2:
- hint(None, global_merge_point=True)
- total += n3
- hint(n4, concrete=True)
+ MyJitDriver.jit_merge_point(n1=n1, n2=n2, n3=n3, n4=n4,
+ total=total)
+ MyJitDriver.can_enter_jit(n1=n1, n2=n2, n3=n3, n4=n4,
+ total=total)
+ total += n4
+ total *= n2
hint(n3, concrete=True)
hint(n2, concrete=True)
hint(n1, concrete=True)
n2 -= 1
return total
- void = lambda s: None
- ll_function.convert_arguments = [void, int, int, void, int]
+ def main(n2, n4, total):
+ return ll_function(None, n2, None, n4, total)
+
+ res = self.run(main, [7, 3, 100], threshold=2)
+ assert res == main(7, 3, 100)
- res = self.interpret(ll_function, [None, 4, 3, None, 100], [0])
- assert res == ll_function(None, 4, 3, None, 100)
+ res = self.run(main, [7, 3, 100], threshold=1)
+ assert res == main(7, 3, 100)
def test_remembers_across_mp(self):
def ll_function(x, flag):
Modified: pypy/branch/jit-hotpath/pypy/rlib/jit.py
==============================================================================
--- pypy/branch/jit-hotpath/pypy/rlib/jit.py (original)
+++ pypy/branch/jit-hotpath/pypy/rlib/jit.py Sat Mar 15 16:47:55 2008
@@ -178,6 +178,10 @@
def _emulate_method_calls(cls, bookkeeper, livevars_s):
# annotate "cls.on_enter_jit()" if it is defined
+ # on_enter_jit(self) is called with a copy of the value of the
+ # red and green variables. The red variables can be modified
+ # in order to give hints to the JIT about the redboxes. The
+ # green variables should not be changed.
from pypy.annotation import model as annmodel
if hasattr(cls, 'on_enter_jit'):
classdef = bookkeeper.getuniqueclassdef(cls)
More information about the Pypy-commit
mailing list