[pypy-svn] r53231 - in pypy/branch/jit-merging-logic/pypy/jit/timeshifter: . test
cfbolz at codespeak.net
cfbolz at codespeak.net
Tue Apr 1 15:24:01 CEST 2008
Author: cfbolz
Date: Tue Apr 1 15:24:00 2008
New Revision: 53231
Modified:
pypy/branch/jit-merging-logic/pypy/jit/timeshifter/rcontainer.py
pypy/branch/jit-merging-logic/pypy/jit/timeshifter/rtimeshift.py
pypy/branch/jit-merging-logic/pypy/jit/timeshifter/rvalue.py
pypy/branch/jit-merging-logic/pypy/jit/timeshifter/test/test_merging.py
pypy/branch/jit-merging-logic/pypy/jit/timeshifter/test/test_rcontainer.py
Log:
(cfbolz, arigo) One more test passing.
Trying to refactor along the way.
Kill the access_info stuff again
Modified: pypy/branch/jit-merging-logic/pypy/jit/timeshifter/rcontainer.py
==============================================================================
--- pypy/branch/jit-merging-logic/pypy/jit/timeshifter/rcontainer.py (original)
+++ pypy/branch/jit-merging-logic/pypy/jit/timeshifter/rcontainer.py Tue Apr 1 15:24:00 2008
@@ -643,9 +643,9 @@
if self.virtualizable:
self.structdesc = StructTypeDesc(RGenOp, T)
self.redboxcls = rvalue.ll_redboxcls(RESTYPE)
- # fish for the FrozenConst subclass
+ # fish for the getfrozen() static method
dummybox = self.redboxcls(self.gv_default)
- self.frozenconstcls = dummybox.FrozenConstCls
+ self.getfrozen = dummybox.getfrozen
self.immutable = deref(PTRTYPE)._hints.get('immutable', False)
Modified: pypy/branch/jit-merging-logic/pypy/jit/timeshifter/rtimeshift.py
==============================================================================
--- pypy/branch/jit-merging-logic/pypy/jit/timeshifter/rtimeshift.py (original)
+++ pypy/branch/jit-merging-logic/pypy/jit/timeshifter/rtimeshift.py Tue Apr 1 15:24:00 2008
@@ -168,7 +168,7 @@
result = fielddesc.makebox(jitstate, resgv)
fz = argbox.most_recent_frozen
if fz is not None:
- newfz = fz.get_const_child(fielddesc, resgv)
+ newfz = fz.get_ghost_child(fielddesc, resgv)
result.most_recent_frozen = newfz
return result
return argbox.op_getfield(jitstate, fielddesc)
Modified: pypy/branch/jit-merging-logic/pypy/jit/timeshifter/rvalue.py
==============================================================================
--- pypy/branch/jit-merging-logic/pypy/jit/timeshifter/rvalue.py (original)
+++ pypy/branch/jit-merging-logic/pypy/jit/timeshifter/rvalue.py Tue Apr 1 15:24:00 2008
@@ -64,8 +64,7 @@
return bool(self.genvar) and self.genvar.is_const
def getkind(self):
- if self.genvar is None:
- return None
+ assert self.genvar is not None
return self.genvar.getkind()
def getgenvar(self, jitstate):
@@ -84,6 +83,25 @@
incoming.append(self)
memo[self] = None
+ def freeze(self, memo):
+ memo = memo.boxes
+ try:
+ return memo[self]
+ except KeyError:
+ assert self.genvar is not None
+ result = self.most_recent_frozen
+ if result is None:
+ result = self.getfrozen(self.genvar)
+ self.most_recent_frozen = result
+ else:
+ # sanity-check the most_recent_frozen object
+ if self.genvar.is_const:
+ assert isinstance(result, FrozenConst)
+ else:
+ assert isinstance(result, FrozenVar)
+ memo[self] = result
+ return result
+
def forcevar(self, jitstate, memo, forget_nonzeroness):
if self.is_constant():
# cannot mutate constant boxes in-place
@@ -172,20 +190,13 @@
result = memo[self] = IntRedBox(self.genvar)
return result
- def freeze(self, memo):
- memo = memo.boxes
- try:
- return memo[self]
- except KeyError:
- result = self.most_recent_frozen
- if result is None:
- if self.is_constant():
- result = FrozenIntConst(self.genvar)
- else:
- result = FrozenIntVar()
- self.most_recent_frozen = result
- memo[self] = result
- return result
+ @staticmethod
+ def getfrozen(gv_value):
+ if gv_value.is_const:
+ return FrozenIntConst(gv_value)
+ else:
+ return FrozenIntVar()
+
class BoolRedBox(RedBox):
# XXX make true and false singletons?
@@ -214,18 +225,13 @@
result.iftrue = [effect.copy(memo) for effect in self.iftrue]
return result
- def freeze(self, memo):
- memo = memo.boxes
- try:
- return memo[self]
- except KeyError:
- xxx # use self.most_recent_frozen
- if self.is_constant():
- result = FrozenBoolConst(self.genvar)
- else:
- result = FrozenBoolVar()
- memo[self] = result
- return result
+ @staticmethod
+ def getfrozen(gv_value):
+ if gv_value.is_const:
+ return FrozenBoolConst(gv_value)
+ else:
+ return FrozenBoolVar()
+
class DoubleRedBox(RedBox):
"A red box that contains a constant double-precision floating point value."
@@ -238,34 +244,12 @@
result = memo[self] = DoubleRedBox(self.genvar)
return result
- def freeze(self, memo):
- memo = memo.boxes
- try:
- return memo[self]
- except KeyError:
- xxx # use self.most_recent_frozen
- if self.is_constant():
- result = FrozenDoubleConst(self.genvar)
- else:
- result = FrozenDoubleVar()
- memo[self] = result
- return result
-
-
-class AccessInfo(object):
- def __init__(self):
- self.read_fields = 0
- self.write_fields = 0
- # XXX what else is needed?
-
- def __repr__(self):
- return "<AccessInfo read_fields=%s, write_fields=%s>" % (
- self.read_fields, self.write_fields)
-
- def copy(self):
- result = AccessInfo()
- result.read_fields = self.read_fields
- result.write_fields = self.write_fields
+ @staticmethod
+ def getfrozen(gv_value):
+ if gv_value.is_const:
+ return FrozenDoubleConst(gv_value)
+ else:
+ return FrozenDoubleVar()
class AbstractPtrRedBox(RedBox):
@@ -280,7 +264,6 @@
if genvar is not None and genvar.is_const:
known_nonzero = bool(self._revealconst(genvar))
self.known_nonzero = known_nonzero
- self.access_info = AccessInfo()
def setgenvar(self, newgenvar):
RedBox.setgenvar(self, newgenvar)
@@ -325,8 +308,6 @@
boxmemo[self] = result
if self.content:
result.content = self.content.copy(memo)
- # XXX is this correct?
- result.access_info = self.access_info
assert isinstance(result, AbstractPtrRedBox)
return result
@@ -349,11 +330,12 @@
except KeyError:
content = self.content
if content is None:
+ assert self.genvar is not None
result = self.most_recent_frozen
if result is None:
if self.genvar.is_const:
result = self.FrozenPtrConst(self.genvar)
- elif content is None:
+ else:
result = self.FrozenPtrVar(self.known_nonzero)
self.most_recent_frozen = result
else:
@@ -362,26 +344,25 @@
assert isinstance(result, self.FrozenPtrConst)
else:
assert isinstance(result, self.FrozenPtrVar)
+ return result
+ self.most_recent_frozen = None # for now
+ if not self.genvar:
+ from pypy.jit.timeshifter import rcontainer
+ assert isinstance(content, rcontainer.VirtualContainer)
+ result = self.FrozenPtrVirtual()
+ # store the result in the memo before content.freeze(),
+ # for recursive data structures
boxmemo[self] = result
+ result.fz_content = content.freeze(memo)
else:
- self.most_recent_frozen = None # for now
- if not self.genvar:
- from pypy.jit.timeshifter import rcontainer
- assert isinstance(content, rcontainer.VirtualContainer)
- result = self.FrozenPtrVirtual()
- # store the result in the memo before content.freeze(),
- # for recursive data structures
- boxmemo[self] = result
- result.fz_content = content.freeze(memo)
- else:
- # if self.content is not None, it's a PartialDataStruct
- from pypy.jit.timeshifter import rcontainer
- assert isinstance(content, rcontainer.PartialDataStruct)
- result = self.FrozenPtrVarWithPartialData(known_nonzero=True)
- # store the result in the memo before content.freeze(),
- # for recursive data structures
- boxmemo[self] = result
- result.fz_partialcontent = content.partialfreeze(memo)
+ # if self.content is not None, it's a PartialDataStruct
+ from pypy.jit.timeshifter import rcontainer
+ assert isinstance(content, rcontainer.PartialDataStruct)
+ result = self.FrozenPtrVarWithPartialData(known_nonzero=True)
+ # store the result in the memo before content.freeze(),
+ # for recursive data structures
+ boxmemo[self] = result
+ result.fz_partialcontent = content.partialfreeze(memo)
return result
def getgenvar(self, jitstate):
@@ -420,7 +401,6 @@
self.content.enter_block(incoming, memo)
def op_getfield(self, jitstate, fielddesc):
- self.access_info.read_fields += 1
self.learn_nonzeroness(jitstate, True)
if self.content is not None:
box = self.content.op_getfield(jitstate, fielddesc)
@@ -430,10 +410,13 @@
box = fielddesc.generate_get(jitstate, gv_ptr)
if fielddesc.immutable:
self.remember_field(fielddesc, box)
+ fz = self.most_recent_frozen
+ if fz is not None:
+ newfz = fz.get_ghost_child(fielddesc, box.genvar)
+ box.most_recent_frozen = newfz
return box
def op_setfield(self, jitstate, fielddesc, valuebox):
- self.access_info.write_fields += 1
self.learn_nonzeroness(jitstate, True)
gv_ptr = self.genvar
if gv_ptr:
@@ -476,9 +459,22 @@
assert self.content is not None
return self.content.op_getsubstruct(jitstate, fielddesc)
+ @staticmethod
+ def getfrozen(gv_value):
+ if gv_value.is_const:
+ return FrozenPtrConst(gv_value)
+ else:
+ return FrozenPtrVar(known_nonzero=False)
+
class InstanceRedBox(AbstractPtrRedBox, OOTypeMixin):
- pass
+
+ @staticmethod
+ def getfrozen(gv_value):
+ if gv_value.is_const:
+ return FrozenInstanceConst(gv_value)
+ else:
+ return FrozenInstanceVar()
# ____________________________________________________________
@@ -486,6 +482,7 @@
class FrozenValue(object):
"""An abstract value frozen in a saved state.
"""
+ _attrs_ = ['will_be_promoted']
will_be_promoted = False
def is_constant_equal(self, box):
@@ -494,6 +491,11 @@
def is_constant_nullptr(self):
return False
+ def check_future_promotions(self, box, memo):
+ if (self.will_be_promoted and box.is_constant()
+ and not self.is_constant_equal(box)):
+ raise DontMerge
+
class FrozenConst(FrozenValue):
@@ -506,11 +508,6 @@
outgoingvarboxes.append(box)
return False
- def check_future_promotions(self, box, memo):
- if (self.will_be_promoted and box.is_constant()
- and not self.is_constant_equal(box)):
- raise DontMerge
-
class FrozenVar(FrozenValue):
@@ -543,8 +540,6 @@
# XXX could return directly the original IntRedBox
return IntRedBox(self.gv_const)
-IntRedBox.FrozenConstCls = FrozenIntConst
-
class FrozenIntVar(FrozenVar):
@@ -572,8 +567,6 @@
def unfreeze(self, incomingvarboxes, memo):
return BoolRedBox(self.gv_const)
-BoolRedBox.FrozenConstCls = FrozenBoolConst
-
class FrozenBoolVar(FrozenVar):
@@ -600,8 +593,6 @@
def unfreeze(self, incomingvarboxes, memo):
return DoubleRedBox(self.gv_const)
-DoubleRedBox.FrozenConstCls = FrozenDoubleConst
-
class FrozenDoubleVar(FrozenVar):
@@ -616,7 +607,36 @@
return memo[self]
-class FrozenAbstractPtrConst(FrozenConst):
+class FrozenPtrMixin(object):
+ _mixin_ = True
+ ghost_children = None
+
+ def get_ghost_child(self, fielddesc, gv_value):
+ # ghost children of a constant immutable FrozenPtrConst
+ # are only used to track future promotions; they have no
+ # other effect on exactmatch().
+ if self.ghost_children is None:
+ self.ghost_children = {}
+ else:
+ try:
+ return self.ghost_children[fielddesc]
+ except KeyError:
+ pass
+ newfz = fielddesc.getfrozen(gv_value)
+ self.ghost_children[fielddesc] = newfz
+ return newfz
+
+ def check_future_promotions(self, box, memo):
+ FrozenValue.check_future_promotions(self, box, memo)
+ if self.ghost_children is not None:
+ for fielddesc, fz_child in self.ghost_children.items():
+ box_child = box.getfield_dont_generate_code(memo.rgenop,
+ fielddesc)
+ if box_child is not None:
+ fz_child.check_future_promotions(box_child, memo)
+
+
+class FrozenAbstractPtrConst(FrozenPtrMixin, FrozenConst):
def __init__(self, gv_const):
FrozenConst.__init__(self)
@@ -647,43 +667,15 @@
def unfreeze(self, incomingvarboxes, memo):
return self.PtrRedBox(self.gv_const)
- const_children = None
-
- def get_const_child(self, fielddesc, gv_value):
- # constant children of a constant immutable FrozenPtrConst
- # are only used to track future promotions; they have no
- # other effect on exactmatch().
- if self.const_children is None:
- self.const_children = {}
- else:
- try:
- return self.const_children[fielddesc]
- except KeyError:
- pass
- newfz = fielddesc.frozenconstcls(gv_value)
- self.const_children[fielddesc] = newfz
- return newfz
-
- def check_future_promotions(self, box, memo):
- FrozenConst.check_future_promotions(self, box, memo)
- if self.const_children is not None:
- for fielddesc, fz_child in self.const_children.items():
- box_child = box.getfield_dont_generate_code(memo.rgenop,
- fielddesc)
- if box_child is not None:
- fz_child.check_future_promotions(box_child, memo)
-
class FrozenPtrConst(FrozenAbstractPtrConst, LLTypeMixin):
PtrRedBox = PtrRedBox
-PtrRedBox.FrozenConstCls = FrozenPtrConst
class FrozenInstanceConst(FrozenAbstractPtrConst, OOTypeMixin):
PtrRedBox = InstanceRedBox
-InstanceRedBox.FrozenConstCls = FrozenInstanceConst
-class AbstractFrozenPtrVar(FrozenVar):
+class AbstractFrozenPtrVar(FrozenPtrMixin, FrozenVar):
def __init__(self, known_nonzero):
FrozenVar.__init__(self)
@@ -698,13 +690,7 @@
match = FrozenVar.exactmatch(self, box, outgoingvarboxes, memo)
if self.known_nonzero and not box.known_nonzero:
match = False
- if not memo.force_merge:
- if isinstance(box.content, VirtualContainer):
- # heuristic: if a virtual is neither written to, nor read from
- # it might not be "important enough" to keep it virtual
- if not box.access_info.read_fields:
- return match
- raise DontMerge # XXX recursive data structures?
+ self.check_future_promotions(box, memo)
return match
def unfreeze(self, incomingvarboxes, memo):
@@ -736,12 +722,8 @@
exact = FrozenVar.exactmatch(self, box, outgoingvarboxes, memo)
match = exact and partialdatamatch
if not memo.force_merge and not match:
- # heuristic: if a virtual is neither written to, nor read from
- # it might not be "important enough" to keep it virtual
from pypy.jit.timeshifter.rcontainer import VirtualContainer
if isinstance(box.content, VirtualContainer):
- if not box.access_info.read_fields:
- return match
raise DontMerge # XXX recursive data structures?
return match
@@ -751,7 +733,6 @@
def exactmatch(self, box, outgoingvarboxes, memo):
assert isinstance(box, PtrRedBox)
if box.genvar:
- # XXX should we consider self.access_info here too?
raise DontMerge
else:
assert box.content is not None
Modified: pypy/branch/jit-merging-logic/pypy/jit/timeshifter/test/test_merging.py
==============================================================================
--- pypy/branch/jit-merging-logic/pypy/jit/timeshifter/test/test_merging.py (original)
+++ pypy/branch/jit-merging-logic/pypy/jit/timeshifter/test/test_merging.py Tue Apr 1 15:24:00 2008
@@ -138,3 +138,34 @@
box3 = rvalue.PtrRedBox(FakeGenConst(prebuilt_s3))
memo = rvalue.exactmatch_memo(rgenop)
py.test.raises(rvalue.DontMerge, frozen.exactmatch, box3, [], memo)
+
+ def test_promote_field_of_variable_immutable(self):
+ rgenop = FakeRGenOp()
+ gv = FakeGenVar()
+ box = rvalue.PtrRedBox(gv)
+ frozen = box.freeze(rvalue.freeze_memo())
+ assert box.most_recent_frozen is not None # attached by freeze
+
+ jitstate = FakeJITState()
+
+ x_box = rtimeshift.gengetfield(jitstate, False, self.fielddesc, box)
+ assert not x_box.genvar.is_const
+ assert x_box.most_recent_frozen is not None # attached by gengetfield()
+ x_box.see_promote()
+
+ memo = rvalue.exactmatch_memo(rgenop)
+ assert frozen.exactmatch(box, [], memo)
+
+ prebuilt_s2 = lltype.malloc(self.STRUCT)
+ prebuilt_s2.x = 42
+ box2 = rvalue.PtrRedBox(FakeGenConst(prebuilt_s2))
+ memo = rvalue.exactmatch_memo(rgenop)
+ py.test.raises(rvalue.DontMerge, frozen.exactmatch, box2, [], memo)
+
+ gv2 = FakeGenVar()
+ box3 = rvalue.PtrRedBox(gv2)
+ x_box3 = rtimeshift.gengetfield(jitstate, False, self.fielddesc, box3)
+ x_box3.see_promote()
+ x_box3.setgenvar(FakeGenConst(42))
+ memo = rvalue.exactmatch_memo(rgenop)
+ py.test.raises(rvalue.DontMerge, frozen.exactmatch, box3, [], memo)
Modified: pypy/branch/jit-merging-logic/pypy/jit/timeshifter/test/test_rcontainer.py
==============================================================================
--- pypy/branch/jit-merging-logic/pypy/jit/timeshifter/test/test_rcontainer.py (original)
+++ pypy/branch/jit-merging-logic/pypy/jit/timeshifter/test/test_rcontainer.py Tue Apr 1 15:24:00 2008
@@ -99,27 +99,6 @@
# constbox20 in oldbox.
- def test_merge_with_ptrvar(self):
- DontMerge = rvalue.DontMerge
- V0 = FakeGenVar()
- ptrbox = rvalue.PtrRedBox(V0)
- jitstate = FakeJITState()
- S = self.STRUCT
- constbox20 = makebox(20)
- oldbox = vmalloc(S, constbox20)
-
- # do a getfield to prevent a merge
- box2 = oldbox.op_getfield(jitstate, self.fielddesc)
- assert box2 is constbox20
- assert oldbox.access_info.read_fields == 1
- frozenbox = oldbox.freeze(rvalue.freeze_memo())
- # check that ptrbox does not match the frozen virtual struct ever
- py.test.raises(DontMerge, self.match, frozenbox, ptrbox, [ptrbox])
-
- # try it the other way round
- frozenptrbox = ptrbox.freeze(rvalue.freeze_memo())
- py.test.raises(DontMerge, self.match, frozenptrbox, oldbox, [oldbox])
-
def test_merge_with_ptrvar_virtual_never_read(self):
DontMerge = rvalue.DontMerge
V0 = FakeGenVar()
More information about the Pypy-commit
mailing list