Author: Hakan Ardo <[email protected]>
Branch: jit-usable_retrace_2
Changeset: r51030:75ff444ada2d
Date: 2012-01-04 19:25 +0100
http://bitbucket.org/pypy/pypy/changeset/75ff444ada2d/
Log: Make kill_consts separate from force_at_end_of_preamble to be able
to call it earlier and thereby allow the jumpargs to be updated
which is needed for non-virtal constants among the original jumpargs
diff --git a/pypy/jit/metainterp/optimizeopt/optimizer.py
b/pypy/jit/metainterp/optimizeopt/optimizer.py
--- a/pypy/jit/metainterp/optimizeopt/optimizer.py
+++ b/pypy/jit/metainterp/optimizeopt/optimizer.py
@@ -124,15 +124,18 @@
def get_key_box(self):
return self.box
- def force_at_end_of_preamble(self, already_forced, optforce):
- if optforce.optimizer.kill_consts_at_end_of_preamble and
self.is_constant():
+ def kill_consts(self, already_killed, opt):
+ if self.is_constant():
constbox = self.box
box = constbox.clonebox()
op = ResOperation(rop.SAME_AS, [constbox], box)
- optforce.optimizer._newoperations.append(op)
+ opt.optimizer._newoperations.append(op)
return OptValue(box)
return self
+ def force_at_end_of_preamble(self, already_forced, optforce):
+ return self
+
def get_args_for_fail(self, modifier):
pass
@@ -358,7 +361,6 @@
self.optimizer = self
self.optpure = None
self.optearlyforce = None
- self.kill_consts_at_end_of_preamble = False
if loop is not None:
self.call_pure_results = loop.call_pure_results
diff --git a/pypy/jit/metainterp/optimizeopt/unroll.py
b/pypy/jit/metainterp/optimizeopt/unroll.py
--- a/pypy/jit/metainterp/optimizeopt/unroll.py
+++ b/pypy/jit/metainterp/optimizeopt/unroll.py
@@ -152,7 +152,12 @@
# At the end of a bridge about to force a retrcae
debug_print('Generalize for retrace')
KillIntBounds(self.optimizer).apply()
- self.optimizer.kill_consts_at_end_of_preamble = True
+
+ jump_args = stop_label.getarglist()
+ already_killed = {}
+ values = [self.getvalue(box).kill_consts(already_killed,
self.optimizer)
+ for box in jump_args]
+ stop_label.initarglist([v.get_key_box() for v in values])
def jump_to_start_label(self, start_label, stop_label):
if not start_label or not stop_label:
diff --git a/pypy/jit/metainterp/optimizeopt/virtualize.py
b/pypy/jit/metainterp/optimizeopt/virtualize.py
--- a/pypy/jit/metainterp/optimizeopt/virtualize.py
+++ b/pypy/jit/metainterp/optimizeopt/virtualize.py
@@ -40,6 +40,9 @@
return value
return OptValue(self.force_box(optforce))
+ def kill_consts(self, already_killed, opt):
+ return self
+
def make_virtual_info(self, modifier, fieldnums):
if fieldnums is None:
return self._make_virtual(modifier)
@@ -128,6 +131,15 @@
self._fields[ofs] =
self._fields[ofs].force_at_end_of_preamble(already_forced, optforce)
return self
+ def kill_consts(self, already_killed, opt):
+ if self in already_killed:
+ return self
+ already_killed[self] = self
+ if self._fields:
+ for ofs in self._fields.keys():
+ self._fields[ofs] =
self._fields[ofs].kill_consts(already_killed, opt)
+ return self
+
def _really_force(self, optforce):
op = self.source_op
assert op is not None
@@ -262,6 +274,14 @@
self._items[index] =
self._items[index].force_at_end_of_preamble(already_forced, optforce)
return self
+ def kill_consts(self, already_killed, opt):
+ if self in already_killed:
+ return self
+ already_killed[self] = self
+ for index in range(len(self._items)):
+ self._items[index] =
self._items[index].kill_consts(already_killed, opt)
+ return self
+
def _really_force(self, optforce):
assert self.source_op is not None
if not we_are_translated():
@@ -357,6 +377,15 @@
self._items[index][descr] =
self._items[index][descr].force_at_end_of_preamble(already_forced, optforce)
return self
+ def kill_consts(self, already_killed, opt):
+ if self in already_killed:
+ return self
+ already_killed[self] = self
+ for index in range(len(self._items)):
+ for descr in self._items[index].keys():
+ self._items[index][descr] =
self._items[index][descr].kill_consts(already_killed, opt)
+ return self
+
def _make_virtual(self, modifier):
return modifier.make_varraystruct(self.arraydescr,
self._get_list_of_descrs())
diff --git a/pypy/jit/metainterp/optimizeopt/virtualstate.py
b/pypy/jit/metainterp/optimizeopt/virtualstate.py
--- a/pypy/jit/metainterp/optimizeopt/virtualstate.py
+++ b/pypy/jit/metainterp/optimizeopt/virtualstate.py
@@ -520,8 +520,7 @@
def getvalue(self, box):
return self.optimizer.getvalue(box)
- def state(self, box):
- value = self.getvalue(box)
+ def state(self, value):
box = value.get_key_box()
try:
info = self.info[box]
@@ -529,7 +528,7 @@
if value.is_virtual():
self.info[box] = info = value.make_virtual_info(self, None)
flds = self.fieldboxes[box]
- info.fieldstate = [self.state(b) for b in flds]
+ info.fieldstate = [self.state(self.getvalue(b)) for b in flds]
else:
self.info[box] = info = self.make_not_virtual(value)
return info
@@ -550,7 +549,7 @@
value.get_args_for_fail(self)
else:
self.make_not_virtual(value)
- return VirtualState([self.state(box) for box in jump_args])
+ return VirtualState([self.state(value) for value in values])
def make_not_virtual(self, value):
return NotVirtualStateInfo(value)
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
@@ -949,6 +949,151 @@
self.check_aborted_count(0)
self.check_target_token_count(3)
+ def test_nested_loops_const(self):
+ class Int(object):
+ def __init__(self, val):
+ self.val = val
+ bytecode = "iajb+JI"
+ def get_printable_location(i):
+ return "%d: %s" % (i, bytecode[i])
+ myjitdriver = JitDriver(greens = ['pc'], reds = ['n', 'c', 'sa', 'i',
'j'],
+ get_printable_location=get_printable_location)
+ def f(n):
+ pc = sa = c = 0
+ i = j = Int(0)
+ while pc < len(bytecode):
+ myjitdriver.jit_merge_point(pc=pc, n=n, sa=sa, i=i, j=j, c=c)
+ op = bytecode[pc]
+ if op == 'i':
+ i = Int(0)
+ elif op == 'j':
+ j = Int(0)
+ elif op == '+':
+ sa += (i.val + 2) * (j.val + 2) + c
+ elif op == 'a':
+ i = Int(i.val + 1)
+ c = 42
+ elif op == 'b':
+ j = Int(j.val + 1)
+ c = 7
+ elif op == 'J':
+ if j.val < n:
+ pc -= 2
+ myjitdriver.can_enter_jit(pc=pc, n=n, sa=sa, i=i, j=j,
c=c)
+ continue
+ elif op == 'I':
+ if i.val < n:
+ pc -= 5
+ myjitdriver.can_enter_jit(pc=pc, n=n, sa=sa, i=i, j=j,
c=c)
+ continue
+ pc += 1
+ return sa
+
+ res = self.meta_interp(f, [10])
+ assert res == f(10)
+ self.check_aborted_count(0)
+ self.check_target_token_count(3)
+ self.check_trace_count(3)
+ self.check_resops(int_mul=3)
+
+ def test_nested_loops_const_array(self):
+ class Int(object):
+ def __init__(self, val):
+ self.val = val
+ bytecode = "iajb+JI"
+ def get_printable_location(i):
+ return "%d: %s" % (i, bytecode[i])
+ myjitdriver = JitDriver(greens = ['pc'], reds = ['n', 'sa', 'i', 'j',
'c'],
+ get_printable_location=get_printable_location)
+ def f(n):
+ pc = sa = 0
+ c = [0]
+ i = j = Int(0)
+ while pc < len(bytecode):
+ myjitdriver.jit_merge_point(pc=pc, n=n, sa=sa, i=i, j=j, c=c)
+ op = bytecode[pc]
+ if op == 'i':
+ i = Int(0)
+ elif op == 'j':
+ j = Int(0)
+ elif op == '+':
+ sa += (i.val + 2) * (j.val + 2) + c[0]
+ elif op == 'a':
+ i = Int(i.val + 1)
+ c = [42, 2]
+ elif op == 'b':
+ j = Int(j.val + 1)
+ c = [7, 3]
+ elif op == 'J':
+ if j.val < n:
+ pc -= 2
+ myjitdriver.can_enter_jit(pc=pc, n=n, sa=sa, i=i, j=j,
c=c)
+ continue
+ elif op == 'I':
+ if i.val < n:
+ pc -= 5
+ myjitdriver.can_enter_jit(pc=pc, n=n, sa=sa, i=i, j=j,
c=c)
+ continue
+ pc += 1
+ return sa
+
+ res = self.meta_interp(f, [10])
+ assert res == f(10)
+ self.check_aborted_count(0)
+ self.check_target_token_count(3)
+ self.check_trace_count(3)
+ self.check_resops(int_mul=3)
+
+ def test_nested_loops_const_dict(self):
+ class Int(object):
+ def __init__(self, val):
+ self.val = val
+ bytecode = "iajb+JI"
+ def get_printable_location(i):
+ return "%d: %s" % (i, bytecode[i])
+ myjitdriver = JitDriver(greens = ['pc'], reds = ['n', 'sa', 'i', 'j',
'c'],
+ get_printable_location=get_printable_location)
+ def f(n):
+ pc = sa = 0
+ c = {}
+ i = j = Int(0)
+ while pc < len(bytecode):
+ myjitdriver.jit_merge_point(pc=pc, n=n, sa=sa, i=i, j=j, c=c)
+ op = bytecode[pc]
+ if op == 'i':
+ i = Int(0)
+ elif op == 'j':
+ j = Int(0)
+ elif op == '+':
+ sa += (i.val + 2) * (j.val + 2) + c[0]
+ elif op == 'a':
+ i = Int(i.val + 1)
+ c = {}
+ c[0] = 42
+ elif op == 'b':
+ j = Int(j.val + 1)
+ c = {}
+ c[0] = 7
+ elif op == 'J':
+ if j.val < n:
+ pc -= 2
+ myjitdriver.can_enter_jit(pc=pc, n=n, sa=sa, i=i, j=j,
c=c)
+ continue
+ elif op == 'I':
+ if i.val < n:
+ pc -= 5
+ myjitdriver.can_enter_jit(pc=pc, n=n, sa=sa, i=i, j=j,
c=c)
+ continue
+ pc += 1
+ return sa
+
+ res = self.meta_interp(f, [10])
+ assert res == f(10)
+ self.check_aborted_count(0)
+ self.check_target_token_count(3)
+ self.check_trace_count(3)
+ self.check_resops(int_mul=3)
+
class VirtualMiscTests:
def test_multiple_equal_virtuals(self):
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit