Author: Carl Friedrich Bolz <cfb...@gmx.de> Branch: small-unroll-improvements Changeset: r70507:605961f3e5de Date: 2014-04-09 16:34 +0200 http://bitbucket.org/pypy/pypy/changeset/605961f3e5de/
Log: start using generate_guards to implement generalization_of 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 @@ -57,7 +57,7 @@ info1.position = 0 info2 = NotVirtualStateInfo(value2) info2.position = 0 - return info1.generalization_of(info2, {}, {}) + return info1.generalization_of(info2, {}, {}, LLtypeMixin.cpu) assert isgeneral(OptValue(BoxInt()), OptValue(ConstInt(7))) assert not isgeneral(OptValue(ConstInt(7)), OptValue(BoxInt())) @@ -66,9 +66,10 @@ nonnull = OptValue(BoxPtr()) nonnull.make_nonnull(0) knownclass = OptValue(BoxPtr()) - knownclass.make_constant_class(ConstPtr(self.someptr1), 0) + clsbox = LLtypeMixin.cpu.ts.cls_of_box(BoxPtr(LLtypeMixin.myptr)) + knownclass.make_constant_class(clsbox, 0) const = OptValue(BoxPtr) - const.make_constant_class(ConstPtr(self.someptr1), 0) + const.make_constant_class(clsbox, 0) const.make_constant(ConstPtr(self.someptr1)) inorder = [ptr, nonnull, knownclass, const] for i in range(len(inorder)): @@ -179,12 +180,14 @@ 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 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, {}) 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 @@ -388,7 +388,8 @@ #debug_start('jit-log-virtualstate') #virtual_state.debug_print('Closed loop with ') bad = {} - if not virtual_state.generalization_of(final_virtual_state, bad): + if not virtual_state.generalization_of(final_virtual_state, bad, + cpu=self.optimizer.cpu): # We ended up with a virtual state that is not compatible # and we are thus unable to jump to the start of the loop #final_virtual_state.debug_print("Bad virtual state at end of loop, ", @@ -558,7 +559,9 @@ bad = {} debugmsg = 'Did not match ' - if target.virtual_state.generalization_of(virtual_state, bad): + if target.virtual_state.generalization_of( + virtual_state, bad, + cpu = self.optimizer.cpu): ok = True debugmsg = 'Matched ' else: 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 @@ -17,16 +17,15 @@ class AbstractVirtualStateInfo(resume.AbstractVirtualInfo): position = -1 - def generalization_of(self, other, renum, bad): - assert self.position != -1 - if self.position in renum: - result = renum[self.position] == other.position - else: - renum[self.position] = other.position - result = self.generalization_of_renumbering_done(other, renum, bad) - if not result: - bad[self] = bad[other] = None - return result + def generalization_of(self, other, renum, bad, cpu=None): + # cpu can be None for testing only + guards = [] + try: + self.generate_guards(other, None, cpu, guards, renum, bad) + assert not guards + return True + except InvalidLoop: + return False def generate_guards(self, other, value, cpu, extra_guards, renum, bad=None): """ generate guards (output in the list extra_guards) that make runtime @@ -38,6 +37,7 @@ 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 self.position != -1 if bad is None: bad = {} assert value is None or isinstance(value, OptValue) @@ -93,43 +93,27 @@ def __init__(self, fielddescrs): self.fielddescrs = fielddescrs - def generalization_of_renumbering_done(self, other, renum, bad): + def _generate_guards(self, other, value, cpu, extra_guards, renum, bad): if not self._generalization_of_structpart(other): - return False + raise InvalidLoop("different kinds of structs") assert isinstance(other, AbstractVirtualStructStateInfo) assert len(self.fielddescrs) == len(self.fieldstate) assert len(other.fielddescrs) == len(other.fieldstate) + if value is not None: + assert isinstance(value, virtualize.AbstractVirtualStructValue) + assert value.is_virtual() + if len(self.fielddescrs) != len(other.fielddescrs): - return False + raise InvalidLoop("field descrs don't match") for i in range(len(self.fielddescrs)): if other.fielddescrs[i] is not self.fielddescrs[i]: - return False - if not self.fieldstate[i].generalization_of(other.fieldstate[i], - renum, bad): - return False - - return True - - - def _generate_guards(self, other, value, cpu, extra_guards, renum, bad): - if not self._generalization_of_structpart(other): - raise InvalidLoop("XXX") - - assert isinstance(other, AbstractVirtualStructStateInfo) - assert len(self.fielddescrs) == len(self.fieldstate) - assert len(other.fielddescrs) == len(other.fieldstate) - assert isinstance(value, virtualize.AbstractVirtualStructValue) - assert value.is_virtual() - - if len(self.fielddescrs) != len(other.fielddescrs): - raise InvalidLoop("XXX") - - for i in range(len(self.fielddescrs)): - if other.fielddescrs[i] is not self.fielddescrs[i]: - raise InvalidLoop("XXX") - v = value._fields[self.fielddescrs[i]] # must be there + raise InvalidLoop("field descrs don't match") + if value is not None: + 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) @@ -187,18 +171,18 @@ def __init__(self, arraydescr): self.arraydescr = arraydescr - def generalization_of_renumbering_done(self, other, renum, bad): + def _generate_guards(self, other, value, cpu, extra_guards, renum, bad): if not isinstance(other, VArrayStateInfo): - return False + raise InvalidLoop("other is not an array") if self.arraydescr is not other.arraydescr: - return False + raise InvalidLoop("other is a different kind of array") if len(self.fieldstate) != len(other.fieldstate): - return False + raise InvalidLoop("other has a different length") for i in range(len(self.fieldstate)): - if not self.fieldstate[i].generalization_of(other.fieldstate[i], - renum, bad): - return False - return True + # XXX value + self.fieldstate[i].generate_guards(other.fieldstate[i], + None, cpu, extra_guards, + renum, bad) def enum_forced_boxes(self, boxes, value, optimizer): if not isinstance(value, virtualize.VArrayValue): @@ -226,27 +210,29 @@ self.arraydescr = arraydescr self.fielddescrs = fielddescrs - def generalization_of_renumbering_done(self, other, renum, bad): + def _generate_guards(self, other, value, cpu, extra_guards, renum, bad): + # XXX this needs a test in test_virtualstate!!! if not isinstance(other, VArrayStructStateInfo): - return False + raise InvalidLoop("other is not an VArrayStructStateInfo") if not self.arraydescr is not other.arraydescr: - return False + raise InvalidLoop("other is a different kind of array") if len(self.fielddescrs) != len(other.fielddescrs): - return False + raise InvalidLoop("other has a different length") p = 0 for i in range(len(self.fielddescrs)): if len(self.fielddescrs[i]) != len(other.fielddescrs[i]): - return False + raise InvalidLoop("other has a different length") for j in range(len(self.fielddescrs[i])): if self.fielddescrs[i][j] is not other.fielddescrs[i][j]: - return False - if not self.fieldstate[p].generalization_of(other.fieldstate[p], - renum, bad): - return False + raise InvalidLoop("other has a different length") + self.fieldstate[p].generate_guards(other.fieldstate[p], + None, # XXX + cpu, + extra_guards, + renum, bad) p += 1 - return True def _enum(self, virtual_state): for s in self.fieldstate: @@ -315,17 +301,15 @@ return True def _generate_guards(self, other, value, cpu, extra_guards, renum, bad): - if value is not None: + if value is None or self.is_opaque: + box = None # generating guards for opaque pointers isn't safe + else: box = value.box - else: - box = None if not isinstance(other, NotVirtualStateInfo): raise InvalidLoop('The VirtualStates does not match as a ' + 'virtual appears where a pointer is needed ' + 'and it is too late to force it.') - if self.is_opaque: - raise InvalidLoop('Generating guards for opaque pointers is not safe') if self.lenbound and not self.lenbound.generalization_of(other.lenbound): raise InvalidLoop() _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit