Author: Carl Friedrich Bolz <[email protected]>
Branch: small-unroll-improvements
Changeset: r70513:25dfebb4f119
Date: 2014-04-09 17:31 +0200
http://bitbucket.org/pypy/pypy/changeset/25dfebb4f119/
Log: change the generate_guards interface to not have to pass around four
variables (not quite happy with the result)
diff --git a/rpython/jit/metainterp/optimizeopt/test/test_virtualstate.py
b/rpython/jit/metainterp/optimizeopt/test/test_virtualstate.py
--- a/rpython/jit/metainterp/optimizeopt/test/test_virtualstate.py
+++ b/rpython/jit/metainterp/optimizeopt/test/test_virtualstate.py
@@ -2,7 +2,7 @@
import py
from rpython.jit.metainterp.optimize import InvalidLoop
from rpython.jit.metainterp.optimizeopt.virtualstate import VirtualStateInfo,
VStructStateInfo, \
- VArrayStateInfo, NotVirtualStateInfo, VirtualState, ShortBoxes
+ VArrayStateInfo, NotVirtualStateInfo, VirtualState, ShortBoxes,
GenerateGuardState
from rpython.jit.metainterp.optimizeopt.optimizer import OptValue
from rpython.jit.metainterp.history import BoxInt, BoxFloat, BoxPtr, ConstInt,
ConstPtr
from rpython.rtyper.lltypesystem import lltype, llmemory
@@ -162,9 +162,9 @@
if inputargs is None:
inputargs = [box]
info1.position = info2.position = 0
- guards = []
- info1.generate_guards(info2, value, self.cpu, guards, {})
- self.compare(guards, expected, inputargs)
+ state = GenerateGuardState(self.cpu)
+ info1.generate_guards(info2, value, state)
+ self.compare(state.extra_guards, expected, inputargs)
def compare(self, guards, expected, inputargs):
loop = self.parse(expected)
@@ -181,16 +181,17 @@
def check_no_guards(self, info1, info2, box_or_value=None):
value, _ = self._box_or_value(box_or_value)
info1.position = info2.position = 0
- guards = []
- info1.generate_guards(info2, value, self.cpu, guards, {})
- assert not guards
+ state = GenerateGuardState(self.cpu)
+ info1.generate_guards(info2, value, state)
+ assert not state.extra_guards
def check_invalid(self, info1, info2, box_or_value=None):
value, _ = self._box_or_value(box_or_value)
info1.position = info2.position = 0
guards = []
with py.test.raises(InvalidLoop):
- info1.generate_guards(info2, value, self.cpu, guards, {})
+ state = GenerateGuardState(self.cpu)
+ info1.generate_guards(info2, value, state)
def test_nonvirtual_all_combinations(self):
# set up infos
@@ -422,18 +423,15 @@
guard_nonnull(p0) []
guard_class(p0, ConstClass(node_vtable)) []
"""
- guards = []
- vstate1.generate_guards(vstate2, [value, value], self.cpu, guards)
- self.compare(guards, expected, [self.nodebox])
+ state = vstate1.generate_guards(vstate2, [value, value], self.cpu)
+ self.compare(state.extra_guards, expected, [self.nodebox])
with py.test.raises(InvalidLoop):
- guards = []
vstate1.generate_guards(vstate3, [value, value],
- self.cpu, guards)
+ self.cpu)
with py.test.raises(InvalidLoop):
- guards = []
vstate2.generate_guards(vstate3, [value, value],
- self.cpu, guards)
+ self.cpu)
def test_generate_guards_on_virtual_fields_matches(self):
diff --git a/rpython/jit/metainterp/optimizeopt/unroll.py
b/rpython/jit/metainterp/optimizeopt/unroll.py
--- a/rpython/jit/metainterp/optimizeopt/unroll.py
+++ b/rpython/jit/metainterp/optimizeopt/unroll.py
@@ -557,26 +557,26 @@
ok = False
extra_guards = []
- bad = {}
debugmsg = 'Did not match '
try:
cpu = self.optimizer.cpu
- target.virtual_state.generate_guards(virtual_state,
- values,
- cpu,
- extra_guards)
+ state = target.virtual_state.generate_guards(virtual_state,
+ values,
+ cpu)
ok = True
+ extra_guards = state.extra_guards
if extra_guards:
debugmsg = 'Guarded to match '
else:
debugmsg = 'Matched '
except InvalidLoop:
+ target.virtual_state.debug_print(debugmsg, {}) # XXX
continue
assert patchguardop is not None or (extra_guards == [] and
len(target.short_preamble) == 1)
- target.virtual_state.debug_print(debugmsg, bad)
+ target.virtual_state.debug_print(debugmsg, {})
if ok:
debug_stop('jit-log-virtualstate')
diff --git a/rpython/jit/metainterp/optimizeopt/virtualstate.py
b/rpython/jit/metainterp/optimizeopt/virtualstate.py
--- a/rpython/jit/metainterp/optimizeopt/virtualstate.py
+++ b/rpython/jit/metainterp/optimizeopt/virtualstate.py
@@ -13,6 +13,18 @@
class BadVirtualState(Exception):
pass
+class GenerateGuardState(object):
+ def __init__(self, cpu=None, guards=None, renum=None, bad=None):
+ self.cpu = cpu
+ if guards is None:
+ guards = []
+ self.extra_guards = guards
+ if renum is None:
+ renum = {}
+ self.renum = renum
+ if bad is None:
+ bad = {}
+ self.bad = bad
class AbstractVirtualStateInfo(resume.AbstractVirtualInfo):
position = -1
@@ -20,14 +32,15 @@
def generalization_of(self, other, renum, bad, cpu=None):
# cpu can be None for testing only
guards = []
+ state = GenerateGuardState(cpu, guards, renum, bad)
try:
- self.generate_guards(other, None, cpu, guards, renum, bad)
+ self.generate_guards(other, None, state)
assert not guards
return True
except InvalidLoop:
return False
- def generate_guards(self, other, value, cpu, extra_guards, renum,
bad=None):
+ def generate_guards(self, other, value, state):
""" generate guards (output in the list extra_guards) that make runtime
values of the shape other match the shape of self. if that's not
possible, InvalidLoop is thrown and bad gets keys set which parts of
@@ -37,26 +50,24 @@
the value) as a guiding heuristic whether making such guards makes
sense. if None is passed in for value, no guard is ever generated, and
this function degenerates to a generalization check."""
+ assert value is None or isinstance(value, OptValue)
assert self.position != -1
- if bad is None:
- bad = {}
- assert value is None or isinstance(value, OptValue)
- if self.position in renum:
- if renum[self.position] != other.position:
- bad[self] = bad[other] = None
+ if self.position in state.renum:
+ if state.renum[self.position] != other.position:
+ state.bad[self] = state.bad[other] = None
raise InvalidLoop('The numbering of the virtual states does
not ' +
'match. This means that two virtual fields '
+
'have been set to the same Box in one of the
' +
'virtual states but not in the other.')
else:
- renum[self.position] = other.position
+ state.renum[self.position] = other.position
try:
- self._generate_guards(other, value, cpu, extra_guards, renum,
bad)
+ self._generate_guards(other, value, state)
except InvalidLoop:
- bad[self] = bad[other] = None
+ state.bad[self] = state.bad[other] = None
raise
- def _generate_guards(self, other, value, cpu, extra_guards, renum, bad):
+ def _generate_guards(self, other, value, state):
raise InvalidLoop('Generating guards for making the VirtualStates ' +
'at hand match have not been implemented')
@@ -93,7 +104,7 @@
def __init__(self, fielddescrs):
self.fielddescrs = fielddescrs
- def _generate_guards(self, other, value, cpu, extra_guards, renum, bad):
+ def _generate_guards(self, other, value, state):
if not self._generalization_of_structpart(other):
raise InvalidLoop("different kinds of structs")
@@ -114,7 +125,7 @@
v = value._fields[self.fielddescrs[i]] # must be there
else:
v = None
- self.fieldstate[i].generate_guards(other.fieldstate[i], v, cpu,
extra_guards, renum)
+ self.fieldstate[i].generate_guards(other.fieldstate[i], v, state)
def _generalization_of_structpart(self, other):
@@ -171,7 +182,7 @@
def __init__(self, arraydescr):
self.arraydescr = arraydescr
- def _generate_guards(self, other, value, cpu, extra_guards, renum, bad):
+ def _generate_guards(self, other, value, state):
if not isinstance(other, VArrayStateInfo):
raise InvalidLoop("other is not an array")
if self.arraydescr is not other.arraydescr:
@@ -181,8 +192,7 @@
for i in range(len(self.fieldstate)):
# XXX value
self.fieldstate[i].generate_guards(other.fieldstate[i],
- None, cpu, extra_guards,
- renum, bad)
+ None, state)
def enum_forced_boxes(self, boxes, value, optimizer):
if not isinstance(value, virtualize.VArrayValue):
@@ -210,7 +220,7 @@
self.arraydescr = arraydescr
self.fielddescrs = fielddescrs
- def _generate_guards(self, other, value, cpu, extra_guards, renum, bad):
+ def _generate_guards(self, other, value, state):
# XXX this needs a test in test_virtualstate!!!
if not isinstance(other, VArrayStructStateInfo):
raise InvalidLoop("other is not an VArrayStructStateInfo")
@@ -229,9 +239,7 @@
raise InvalidLoop("other has a different length")
self.fieldstate[p].generate_guards(other.fieldstate[p],
None, # XXX
- cpu,
- extra_guards,
- renum, bad)
+ state)
p += 1
def _enum(self, virtual_state):
@@ -278,7 +286,7 @@
self.lenbound = value.lenbound
- def _generate_guards(self, other, value, cpu, extra_guards, renum, bad):
+ def _generate_guards(self, other, value, state):
if value is None or self.is_opaque:
box = None # generating guards for opaque pointers isn't safe
else:
@@ -291,6 +299,8 @@
'and it is too late to force it.')
+ extra_guards = state.extra_guards
+ cpu = state.cpu
if self.lenbound and not
self.lenbound.generalization_of(other.lenbound):
raise InvalidLoop()
@@ -440,14 +450,13 @@
return False
return True
- def generate_guards(self, other, values, cpu, extra_guards, bad=None):
- if bad is None:
- bad = {}
+ def generate_guards(self, other, values, cpu):
assert len(self.state) == len(other.state) == len(values)
- renum = {}
+ state = GenerateGuardState(cpu)
for i in range(len(self.state)):
self.state[i].generate_guards(other.state[i], values[i],
- cpu, extra_guards, renum, bad)
+ state)
+ return state
def make_inputargs(self, values, optimizer, keyboxes=False):
if optimizer.optearlyforce:
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit