[pypy-svn] r34843 - in pypy/dist/pypy/jit: codegen/i386/test timeshifter timeshifter/test
arigo at codespeak.net
arigo at codespeak.net
Tue Nov 21 23:09:50 CET 2006
Author: arigo
Date: Tue Nov 21 23:09:47 2006
New Revision: 34843
Modified:
pypy/dist/pypy/jit/codegen/i386/test/test_genc_ts.py
pypy/dist/pypy/jit/timeshifter/rcontainer.py
pypy/dist/pypy/jit/timeshifter/rtimeshift.py
pypy/dist/pypy/jit/timeshifter/rvalue.py
pypy/dist/pypy/jit/timeshifter/test/test_promotion.py
pypy/dist/pypy/jit/timeshifter/test/test_timeshift.py
pypy/dist/pypy/jit/timeshifter/vdict.py
pypy/dist/pypy/jit/timeshifter/vlist.py
Log:
(pedronis, arre, arigo)
Make PartialDataStruct survive across merges, at least as long as their
information doesn't conflict with another merged path's information.
(Missing: make recursive PartialDataStructs survive too)
Modified: pypy/dist/pypy/jit/codegen/i386/test/test_genc_ts.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/i386/test/test_genc_ts.py (original)
+++ pypy/dist/pypy/jit/codegen/i386/test/test_genc_ts.py Tue Nov 21 23:09:47 2006
@@ -140,6 +140,9 @@
def check_insns(self, expected=None, **counts):
"Cannot check instructions in the generated assembler."
+ def check_flexswitches(self, expected_count):
+ "Cannot check instructions in the generated assembler."
+
class TestTimeshiftI386(I386TimeshiftingTestMixin,
test_timeshift.TestTimeshift):
Modified: pypy/dist/pypy/jit/timeshifter/rcontainer.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/rcontainer.py (original)
+++ pypy/dist/pypy/jit/timeshifter/rcontainer.py Tue Nov 21 23:09:47 2006
@@ -19,6 +19,15 @@
def op_getsubstruct(self, jitstate, fielddesc):
raise NotImplementedError
+
+class VirtualContainer(AbstractContainer):
+ __slots__ = []
+
+
+class FrozenContainer(AbstractContainer):
+ __slots__ = []
+
+
# ____________________________________________________________
class StructTypeDesc(object):
@@ -158,7 +167,7 @@
# ____________________________________________________________
-class FrozenVirtualStruct(AbstractContainer):
+class FrozenVirtualStruct(FrozenContainer):
def __init__(self, typedesc):
self.typedesc = typedesc
@@ -199,6 +208,7 @@
ownbox = typedesc.factory()
contmemo[self] = ownbox
vstruct = ownbox.content
+ assert isinstance(vstruct, VirtualStruct)
self_boxes = self.fz_content_boxes
for i in range(len(self_boxes)):
fz_box = self_boxes[i]
@@ -207,11 +217,7 @@
return ownbox
-class AbstractStruct(AbstractContainer):
- pass
-
-
-class VirtualStruct(AbstractStruct):
+class VirtualStruct(VirtualContainer):
def __init__(self, typedesc):
self.typedesc = typedesc
@@ -284,8 +290,46 @@
def op_getsubstruct(self, jitstate, fielddesc):
return self.ownbox
+# ____________________________________________________________
-class PartialDataStruct(AbstractStruct):
+class FrozenPartialDataStruct(AbstractContainer):
+
+ def __init__(self):
+ self.fz_data = []
+
+ def getfzbox(self, searchindex):
+ for index, fzbox in self.fz_data:
+ if index == searchindex:
+ return fzbox
+ else:
+ return None
+
+ def match(self, box, partialdatamatch):
+ content = box.content
+ if not isinstance(content, PartialDataStruct):
+ return False
+
+ cankeep = {}
+ for index, subbox in content.data:
+ selfbox = self.getfzbox(index)
+ if selfbox is not None and selfbox.is_constant_equal(subbox):
+ cankeep[index] = None
+ fullmatch = len(cankeep) == len(self.fz_data)
+ try:
+ prevkeep = partialdatamatch[box]
+ except KeyError:
+ partialdatamatch[box] = cankeep
+ else:
+ if prevkeep is not None:
+ d = {}
+ for index in prevkeep:
+ if index in cankeep:
+ d[index] = None
+ partialdatamatch[box] = d
+ return fullmatch
+
+
+class PartialDataStruct(AbstractContainer):
def __init__(self):
self.data = []
@@ -307,6 +351,19 @@
else:
self.data.append((searchindex, box))
+ def partialfreeze(self, memo):
+ contmemo = memo.containers
+ assert self not in contmemo # contmemo no longer used
+ result = contmemo[self] = FrozenPartialDataStruct()
+ for index, box in self.data:
+ if box.is_constant():
+ frozenbox = box.freeze(memo)
+ result.fz_data.append((index, frozenbox))
+ if len(result.fz_data) == 0:
+ return None
+ else:
+ return result
+
def copy(self, memo):
result = PartialDataStruct()
for index, box in self.data:
@@ -325,3 +382,18 @@
contmemo[self] = None
for index, box in self.data:
box.enter_block(incoming, memo)
+
+ def cleanup_partial_data(self, keep):
+ if keep is None:
+ return None
+ j = 0
+ data = self.data
+ for i in range(len(data)):
+ item = data[i]
+ if item[0] in keep:
+ data[j] = item
+ j += 1
+ if j == 0:
+ return None
+ del data[j:]
+ return self
Modified: pypy/dist/pypy/jit/timeshifter/rtimeshift.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/rtimeshift.py (original)
+++ pypy/dist/pypy/jit/timeshifter/rtimeshift.py Tue Nov 21 23:09:47 2006
@@ -2,7 +2,7 @@
from pypy.annotation import model as annmodel
from pypy.rpython.lltypesystem import lltype, lloperation, llmemory
from pypy.jit.hintannotator.model import originalconcretetype
-from pypy.jit.timeshifter import rvalue
+from pypy.jit.timeshifter import rvalue, rcontainer
from pypy.rlib.unroll import unrolling_iterable
from pypy.rpython.annlowlevel import cachedtype, base_ptr_lltype
from pypy.rpython.annlowlevel import cast_instance_to_base_ptr
@@ -219,6 +219,7 @@
outgoingvarboxes = []
res = frozen.exactmatch(jitstate, outgoingvarboxes, memo)
assert res, "exactmatch() failed"
+ cleanup_partial_data(memo.partialdatamatch)
newblock = enter_next_block(jitstate, outgoingvarboxes)
states_dic[key] = frozen, newblock
if global_resumer is not None and global_resumer is not return_marker:
@@ -251,6 +252,7 @@
# We need a more general block. Do it by generalizing all the
# redboxes from outgoingvarboxes, by making them variables.
# Then we make a new block based on this new state.
+ cleanup_partial_data(memo.partialdatamatch)
replace_memo = rvalue.copy_memo()
for box in outgoingvarboxes:
box.forcevar(jitstate.curbuilder, replace_memo)
@@ -262,6 +264,14 @@
return False # continue
retrieve_jitstate_for_merge._annspecialcase_ = "specialize:arglltype(2)"
+def cleanup_partial_data(partialdatamatch):
+ # remove entries from PartialDataStruct unless they matched
+ # their frozen equivalent
+ for box, keep in partialdatamatch.iteritems():
+ content = box.content
+ if isinstance(content, rcontainer.PartialDataStruct):
+ box.content = content.cleanup_partial_data(keep)
+
def merge_generalized(jitstate):
resuming = jitstate.resuming
if resuming is None:
Modified: pypy/dist/pypy/jit/timeshifter/rvalue.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/rvalue.py (original)
+++ pypy/dist/pypy/jit/timeshifter/rvalue.py Tue Nov 21 23:09:47 2006
@@ -14,7 +14,9 @@
return Memo()
def exactmatch_memo():
- return Memo()
+ memo = Memo()
+ memo.partialdatamatch = {}
+ return memo
def copy_memo():
return Memo()
@@ -242,29 +244,35 @@
try:
return boxmemo[self]
except KeyError:
+ content = self.content
if not self.genvar:
- assert self.content is not None
+ from pypy.jit.timeshifter import rcontainer
+ assert isinstance(content, rcontainer.VirtualContainer)
result = FrozenPtrVirtual(self.kind)
boxmemo[self] = result
- result.fz_content = self.content.freeze(memo)
+ result.fz_content = content.freeze(memo)
+ return result
+ elif self.genvar.is_const:
+ result = FrozenPtrConst(self.kind, self.genvar)
+ elif content is None:
+ result = FrozenPtrVar(self.kind)
else:
- if self.is_constant():
- result = FrozenPtrConst(self.kind, self.genvar)
- else:
- result = FrozenPtrVar(self.kind)
- # if self.content is not None, it's a PartialDataStruct
- # - for now, we always remove it while freezing so that
- # we exactly match our frozen version
- # XXX unsure if it's the correct place to do that.
- # XXX maybe in exactmatch??
- self.content = None
+ # if self.content is not None, it's a PartialDataStruct
+ from pypy.jit.timeshifter import rcontainer
+ assert isinstance(content, rcontainer.PartialDataStruct)
+ result = FrozenPtrVarWithPartialData(self.kind)
boxmemo[self] = result
+ result.fz_partialcontent = content.partialfreeze(memo)
+ return result
+ boxmemo[self] = result
return result
def getgenvar(self, builder):
if not self.genvar:
- assert self.content
- self.content.force_runtime_container(builder)
+ content = self.content
+ from pypy.jit.timeshifter import rcontainer
+ assert isinstance(content, rcontainer.VirtualContainer)
+ content.force_runtime_container(builder)
assert self.genvar
return self.genvar
@@ -288,28 +296,21 @@
def __init__(self, kind):
self.kind = kind
+ def is_constant_equal(self, box):
+ return False
-class FrozenIntConst(FrozenValue):
- def __init__(self, kind, gv_const):
- self.kind = kind
- self.gv_const = gv_const
+class FrozenConst(FrozenValue):
def exactmatch(self, box, outgoingvarboxes, memo):
- if (box.is_constant() and
- self.gv_const.revealconst(lltype.Signed) ==
- box.genvar.revealconst(lltype.Signed)):
+ if self.is_constant_equal(box):
return True
else:
outgoingvarboxes.append(box)
return False
- def unfreeze(self, incomingvarboxes, memo):
- # XXX could return directly the original IntRedBox
- return IntRedBox(self.kind, self.gv_const)
-
-class FrozenIntVar(FrozenValue):
+class FrozenVar(FrozenValue):
def exactmatch(self, box, outgoingvarboxes, memo):
memo = memo.boxes
@@ -323,6 +324,25 @@
outgoingvarboxes.append(box)
return False
+
+class FrozenIntConst(FrozenConst):
+
+ def __init__(self, kind, gv_const):
+ self.kind = kind
+ self.gv_const = gv_const
+
+ def is_constant_equal(self, box):
+ return (box.is_constant() and
+ self.gv_const.revealconst(lltype.Signed) ==
+ box.genvar.revealconst(lltype.Signed))
+
+ def unfreeze(self, incomingvarboxes, memo):
+ # XXX could return directly the original IntRedBox
+ return IntRedBox(self.kind, self.gv_const)
+
+
+class FrozenIntVar(FrozenVar):
+
def unfreeze(self, incomingvarboxes, memo):
memo = memo.boxes
if self not in memo:
@@ -334,38 +354,22 @@
return memo[self]
-class FrozenDoubleConst(FrozenValue):
+class FrozenDoubleConst(FrozenConst):
def __init__(self, kind, gv_const):
self.kind = kind
self.gv_const = gv_const
- def exactmatch(self, box, outgoingvarboxes, memo):
- if (box.is_constant() and
- self.gv_const.revealconst(lltype.Float) ==
- box.genvar.revealconst(lltype.Float)):
- return True
- else:
- outgoingvarboxes.append(box)
- return False
+ def is_constant_equal(self, box):
+ return (box.is_constant() and
+ self.gv_const.revealconst(lltype.Float) ==
+ box.genvar.revealconst(lltype.Float))
def unfreeze(self, incomingvarboxes, memo):
return DoubleRedBox(self.kind, self.gv_const)
-class FrozenDoubleVar(FrozenValue):
-
- def exactmatch(self, box, outgoingvarboxes, memo):
- memo = memo.boxes
- if self not in memo:
- memo[self] = box
- outgoingvarboxes.append(box)
- return True
- elif memo[self] is box:
- return True
- else:
- outgoingvarboxes.append(box)
- return False
+class FrozenDoubleVar(FrozenVar):
def unfreeze(self, incomingvarboxes, memo):
memo = memo.boxes
@@ -378,38 +382,32 @@
return memo[self]
-class FrozenPtrConst(FrozenValue):
+class FrozenPtrConst(FrozenConst):
def __init__(self, kind, gv_const):
self.kind = kind
self.gv_const = gv_const
+ def is_constant_equal(self, box):
+ return (box.is_constant() and
+ self.gv_const.revealconst(llmemory.Address) ==
+ box.genvar.revealconst(llmemory.Address))
+
def exactmatch(self, box, outgoingvarboxes, memo):
- if (box.is_constant() and
- self.gv_const.revealconst(llmemory.Address) ==
- box.genvar.revealconst(llmemory.Address)):
- return True
- else:
- outgoingvarboxes.append(box)
- return False
+ assert isinstance(box, PtrRedBox)
+ memo.partialdatamatch[box] = None # could do better
+ return FrozenConst.exactmatch(self, box, outgoingvarboxes, memo)
def unfreeze(self, incomingvarboxes, memo):
return PtrRedBox(self.kind, self.gv_const)
-class FrozenPtrVar(FrozenValue):
+class FrozenPtrVar(FrozenVar):
def exactmatch(self, box, outgoingvarboxes, memo):
- memo = memo.boxes
- if self not in memo:
- memo[self] = box
- outgoingvarboxes.append(box)
- return True
- elif memo[self] is box:
- return True
- else:
- outgoingvarboxes.append(box)
- return False
+ assert isinstance(box, PtrRedBox)
+ memo.partialdatamatch[box] = None
+ return FrozenVar.exactmatch(self, box, outgoingvarboxes, memo)
def unfreeze(self, incomingvarboxes, memo):
memo = memo.boxes
@@ -422,6 +420,19 @@
return memo[self]
+class FrozenPtrVarWithPartialData(FrozenPtrVar):
+
+ def exactmatch(self, box, outgoingvarboxes, memo):
+ if self.fz_partialcontent is None:
+ return FrozenPtrVar.exactmatch(self, box, outgoingvarboxes, memo)
+ assert isinstance(box, PtrRedBox)
+ partialdatamatch = self.fz_partialcontent.match(box,
+ memo.partialdatamatch)
+ # skip the parent's exactmatch()!
+ exact = FrozenVar.exactmatch(self, box, outgoingvarboxes, memo)
+ return exact and partialdatamatch
+
+
class FrozenPtrVirtual(FrozenValue):
def exactmatch(self, box, outgoingvarboxes, memo):
Modified: pypy/dist/pypy/jit/timeshifter/test/test_promotion.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/test/test_promotion.py (original)
+++ pypy/dist/pypy/jit/timeshifter/test/test_promotion.py Tue Nov 21 23:09:47 2006
@@ -263,3 +263,28 @@
res = self.timeshift(ll_function, [5, 100], [0], policy=P_NOVIRTUAL)
assert res == 115
+
+ def test_remembers_across_mp(self):
+ def ll_function(x, flag):
+ hint(None, global_merge_point=True)
+ hint(x.field, promote=True)
+ m = x.field
+ if flag:
+ m += 1 * flag
+ else:
+ m += 2 + flag
+ hint(x.field, promote=True)
+ return m + x.field
+
+ S = lltype.GcStruct('S', ('field', lltype.Signed),
+ hints={'immutable': True})
+
+ def struct_S(string):
+ s = lltype.malloc(S)
+ s.field = int(string)
+ return s
+ ll_function.convert_arguments = [struct_S, int]
+
+ res = self.timeshift(ll_function, ["20", 0], [], policy=P_NOVIRTUAL)
+ assert res == 42
+ self.check_flexswitches(1)
Modified: pypy/dist/pypy/jit/timeshifter/test/test_timeshift.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/test/test_timeshift.py (original)
+++ pypy/dist/pypy/jit/timeshifter/test/test_timeshift.py Tue Nov 21 23:09:47 2006
@@ -5,7 +5,7 @@
from pypy.jit.hintannotator.model import *
from pypy.jit.timeshifter.hrtyper import HintRTyper, originalconcretetype
from pypy.jit.timeshifter import rtimeshift, rvalue
-from pypy.objspace.flow.model import summary
+from pypy.objspace.flow.model import summary, Variable
from pypy.rpython.lltypesystem import lltype, llmemory, rstr
from pypy.rlib.objectmodel import hint, keepalive_until_here
from pypy.rlib.unroll import unrolling_iterable
@@ -320,6 +320,14 @@
for opname, count in counts.items():
assert self.insns.get(opname, 0) == count
+ def check_flexswitches(self, expected_count):
+ count = 0
+ for block in self.residual_graph.iterblocks():
+ if (isinstance(block.exitswitch, Variable) and
+ block.exitswitch.concretetype is lltype.Signed):
+ count += 1
+ assert count == expected_count
+
class TestTimeshift(TimeshiftingTests):
Modified: pypy/dist/pypy/jit/timeshifter/vdict.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/vdict.py (original)
+++ pypy/dist/pypy/jit/timeshifter/vdict.py Tue Nov 21 23:09:47 2006
@@ -1,12 +1,16 @@
import operator
from pypy.rpython.lltypesystem import lltype
from pypy.rpython.lltypesystem import rdict
-from pypy.jit.timeshifter.rcontainer import AbstractContainer, cachedtype
+from pypy.jit.timeshifter.rcontainer import VirtualContainer, FrozenContainer
+from pypy.jit.timeshifter.rcontainer import cachedtype
from pypy.jit.timeshifter import rvalue
from pypy.rlib.objectmodel import r_dict
HASH = lltype.Signed
+# XXXXXXXXXX! ARGH.
+# cannot use a dictionary as the item_boxes at all, because of order issues
+
class LLEqDesc(object):
__metaclass__ = cachedtype
@@ -48,7 +52,7 @@
for key, valuebox in other.item_boxes.iteritems():
self.item_boxes[key] = valuebox.copy(memo)
- def replace(self, memo):
+ def internal_replace(self, memo):
changes = []
for key, valuebox in self.item_boxes.iteritems():
newbox = valuebox.replace(memo)
@@ -137,7 +141,7 @@
TypeDesc = DictTypeDesc
-class AbstractFrozenVirtualDict(AbstractContainer):
+class AbstractFrozenVirtualDict(FrozenContainer):
__slots__ = ('typedesc',)
def __init__(self, typedesc):
@@ -171,10 +175,18 @@
fullmatch = False
return fullmatch
+ def freeze_from(self, vdict, memo):
+ raise NotImplementedError
+
+ def same_keys_as(self, vdict, boxes):
+ raise NotImplementedError
+
-class AbstractVirtualDict(AbstractContainer):
+class AbstractVirtualDict(VirtualContainer):
__slots__ = ('typedesc', 'ownbox') # and no item_boxes
+ FrozenVirtualDict = AbstractFrozenVirtualDict # overridden in subclasses
+
def __init__(self, typedesc):
self.typedesc = typedesc
self.make_item_boxes()
@@ -228,9 +240,30 @@
contmemo = memo.containers
if self not in contmemo:
contmemo[self] = None
- self.replace(memo)
+ self.internal_replace(memo)
self.ownbox = self.ownbox.replace(memo)
+ def make_item_boxes(self):
+ raise NotImplementedError
+
+ def getboxes(self):
+ raise NotImplementedError
+
+ def getitems_and_makeempty(self, rgenop):
+ raise NotImplementedError
+
+ def getitem(self, keybox):
+ raise NotImplementedError
+
+ def setitem(self, keybox, valuebox):
+ raise NotImplementedError
+
+ def copy_from(self, other, memo):
+ raise NotImplementedError
+
+ def internal_replace(self, memo):
+ raise NotImplementedError
+
def oop_newdict(jitstate, oopspecdesc):
return oopspecdesc.typedesc.factory()
Modified: pypy/dist/pypy/jit/timeshifter/vlist.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/vlist.py (original)
+++ pypy/dist/pypy/jit/timeshifter/vlist.py Tue Nov 21 23:09:47 2006
@@ -1,5 +1,6 @@
from pypy.rpython.lltypesystem import lltype
-from pypy.jit.timeshifter.rcontainer import AbstractContainer, cachedtype
+from pypy.jit.timeshifter.rcontainer import VirtualContainer, FrozenContainer
+from pypy.jit.timeshifter.rcontainer import cachedtype
from pypy.jit.timeshifter import rvalue
@@ -39,7 +40,7 @@
TypeDesc = ListTypeDesc
-class FrozenVirtualList(AbstractContainer):
+class FrozenVirtualList(FrozenContainer):
def __init__(self, typedesc):
self.typedesc = typedesc
@@ -74,7 +75,7 @@
return fullmatch
-class VirtualList(AbstractContainer):
+class VirtualList(VirtualContainer):
def __init__(self, typedesc, length=0, itembox=None):
self.typedesc = typedesc
More information about the Pypy-commit
mailing list