[pypy-svn] r33072 - in pypy/dist/pypy/jit: codegen/llgraph timeshifter timeshifter/test
arigo at codespeak.net
arigo at codespeak.net
Mon Oct 9 20:45:42 CEST 2006
Author: arigo
Date: Mon Oct 9 20:45:39 2006
New Revision: 33072
Modified:
pypy/dist/pypy/jit/codegen/llgraph/llimpl.py
pypy/dist/pypy/jit/codegen/llgraph/rgenop.py
pypy/dist/pypy/jit/timeshifter/rcontainer.py
pypy/dist/pypy/jit/timeshifter/rtimeshift.py
pypy/dist/pypy/jit/timeshifter/rtyper.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
Log:
(pedronis, arigo)
Promotion of the __class__ of an instance works. This contains a bit of
pushing and pulling (but also some clean-ups, cheer :-). Some more work
needed.
Modified: pypy/dist/pypy/jit/codegen/llgraph/llimpl.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/llgraph/llimpl.py (original)
+++ pypy/dist/pypy/jit/codegen/llgraph/llimpl.py Mon Oct 9 20:45:39 2006
@@ -7,6 +7,7 @@
from pypy.rpython.lltypesystem import lltype, llmemory, rtupletype
from pypy.objspace.flow import model as flowmodel
from pypy.translator.simplify import eliminate_empty_blocks, join_blocks
+from pypy.translator.unsimplify import varoftype
from pypy.rpython.module.support import init_opaque_object
from pypy.rpython.module.support import to_opaque_object, from_opaque_object
from pypy.rpython.module.support import LLSupport
@@ -251,6 +252,13 @@
block.blockcolor = getcolor()
exitswitch = from_opaque_object(exitswitch)
assert isinstance(exitswitch, flowmodel.Variable)
+ TYPE = exitswitch.concretetype
+ if isinstance(TYPE, lltype.Ptr):
+ # XXX hack!
+ v1 = varoftype(lltype.Signed)
+ block.operations.append(flowmodel.SpaceOperation(
+ 'cast_ptr_to_int', [exitswitch], v1))
+ exitswitch = v1
block.exitswitch = exitswitch
default_link = flowmodel.Link([], None)
default_link.exitcase = "default"
@@ -264,8 +272,12 @@
assert isinstance(exitcase, flowmodel.Constant)
assert isinstance(block.exitswitch, flowmodel.Variable)
case_link = flowmodel.Link([], None)
- case_link.exitcase = exitcase.value
- case_link.llexitcase = exitcase.value
+ exitvalue = exitcase.value
+ if isinstance(lltype.typeOf(exitvalue), lltype.Ptr):
+ # XXX hack!
+ exitvalue = lltype.cast_ptr_to_int(exitvalue)
+ case_link.exitcase = exitvalue
+ case_link.llexitcase = exitvalue
exits = block.exits[:-1] + (case_link,) + block.exits[-1:]
block.recloseblock(*exits)
return to_opaque_object(case_link)
Modified: pypy/dist/pypy/jit/codegen/llgraph/rgenop.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/llgraph/rgenop.py (original)
+++ pypy/dist/pypy/jit/codegen/llgraph/rgenop.py Mon Oct 9 20:45:39 2006
@@ -39,8 +39,10 @@
def __init__(self, b, g):
self.b = b
self.g = g
+ self.cases_gv = []
def add_case(self, gv_case):
+ self.cases_gv.append(gv_case) # not used so far, but keeps ptrs alive
l_case = llimpl.add_case(self.b, gv_case.v)
builder = LLBuilder(self.g)
builder.lnk = l_case
Modified: pypy/dist/pypy/jit/timeshifter/rcontainer.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/rcontainer.py (original)
+++ pypy/dist/pypy/jit/timeshifter/rcontainer.py Mon Oct 9 20:45:39 2006
@@ -60,6 +60,8 @@
def factory(self):
vstruct = VirtualStruct(self)
+ vstruct.content_boxes = [desc.redboxcls(desc.kind, desc.gv_default)
+ for desc in self.fielddescs]
box = rvalue.PtrRedBox(self.innermostdesc.ptrkind)
box.content = vstruct
vstruct.ownbox = box
@@ -179,15 +181,17 @@
vstruct.content_boxes[i] = fz_box.unfreeze(incomingvarboxes,
memo)
return ownbox
-
-class VirtualStruct(AbstractContainer):
+
+class AbstractStruct(AbstractContainer):
+ pass
+
+
+class VirtualStruct(AbstractStruct):
def __init__(self, typedesc):
self.typedesc = typedesc
- self.content_boxes = [desc.redboxcls(desc.kind,
- desc.gv_default)
- for desc in typedesc.fielddescs]
+ #self.content_boxes = ... set in factory()
#self.ownbox = ... set in factory()
def enter_block(self, incoming, memo):
@@ -213,33 +217,29 @@
def freeze(self, memo):
contmemo = memo.containers
- try:
- return contmemo[self]
- except KeyError:
- result = contmemo[self] = FrozenVirtualStruct(self.typedesc)
- frozens = [box.freeze(memo) for box in self.content_boxes]
- result.fz_content_boxes = frozens
- return result
+ assert self not in contmemo # contmemo no longer used
+ result = contmemo[self] = FrozenVirtualStruct(self.typedesc)
+ frozens = [box.freeze(memo) for box in self.content_boxes]
+ result.fz_content_boxes = frozens
+ return result
def copy(self, memo):
contmemo = memo.containers
- try:
- return contmemo[self]
- except KeyError:
- result = contmemo[self] = VirtualStruct(self.typedesc)
- result.content_boxes = [box.copy(memo)
- for box in self.content_boxes]
- result.ownbox = self.ownbox.copy(memo)
- return result
+ assert self not in contmemo # contmemo no longer used
+ result = contmemo[self] = VirtualStruct(self.typedesc)
+ result.content_boxes = [box.copy(memo)
+ for box in self.content_boxes]
+ result.ownbox = self.ownbox.copy(memo)
+ return result
def replace(self, memo):
contmemo = memo.containers
- if self not in contmemo:
- contmemo[self] = None
- content_boxes = self.content_boxes
- for i in range(len(content_boxes)):
- content_boxes[i] = content_boxes[i].replace(memo)
- self.ownbox = self.ownbox.replace(memo)
+ assert self not in contmemo # contmemo no longer used
+ contmemo[self] = None
+ content_boxes = self.content_boxes
+ for i in range(len(content_boxes)):
+ content_boxes[i] = content_boxes[i].replace(memo)
+ self.ownbox = self.ownbox.replace(memo)
def op_getfield(self, jitstate, fielddesc):
return self.content_boxes[fielddesc.fieldindex]
@@ -249,3 +249,45 @@
def op_getsubstruct(self, jitstate, fielddesc):
return self.ownbox
+
+
+class PartialDataStruct(AbstractStruct):
+
+ def __init__(self):
+ self.data = []
+
+ def op_getfield(self, jitstate, fielddesc):
+ searchindex = fielddesc.fieldindex
+ for index, box in self.data:
+ if index == searchindex:
+ return box
+ else:
+ return None
+
+ def remember_field(self, fielddesc, box):
+ searchindex = fielddesc.fieldindex
+ for i in range(len(self.data)):
+ if self.data[i][0] == searchindex:
+ self.data[i] = searchindex, box
+ return
+ else:
+ self.data.append((searchindex, box))
+
+ def copy(self, memo):
+ result = PartialDataStruct()
+ for index, box in self.data:
+ result.data.append((index, box.copy(memo)))
+ return result
+
+ def replace(self, memo):
+ for i in range(len(self.data)):
+ index, box = self.data[i]
+ box = box.replace(memo)
+ self.data[i] = index, box
+
+ def enter_block(self, incoming, memo):
+ contmemo = memo.containers
+ if self not in contmemo:
+ contmemo[self] = None
+ for index, box in self.data:
+ box.enter_block(incoming, memo)
Modified: pypy/dist/pypy/jit/timeshifter/rtimeshift.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/rtimeshift.py (original)
+++ pypy/dist/pypy/jit/timeshifter/rtimeshift.py Mon Oct 9 20:45:39 2006
@@ -101,33 +101,17 @@
res = getattr(rvalue.ll_getvalue(argbox, fielddesc.PTRTYPE),
fielddesc.fieldname)
return rvalue.ll_fromvalue(jitstate, res)
- assert isinstance(argbox, rvalue.PtrRedBox)
- if argbox.content is None:
- gv_ptr = argbox.getgenvar(jitstate.curbuilder)
- return fielddesc.generate_get(jitstate.curbuilder, gv_ptr)
- else:
- return argbox.content.op_getfield(jitstate, fielddesc)
+ return argbox.op_getfield(jitstate, fielddesc)
def ll_gensetfield(jitstate, fielddesc, destbox, valuebox):
- assert isinstance(destbox, rvalue.PtrRedBox)
- if destbox.content is None:
- gv_ptr = destbox.getgenvar(jitstate.curbuilder)
- fielddesc.generate_set(jitstate.curbuilder, gv_ptr, valuebox)
- else:
- destbox.content.op_setfield(jitstate, fielddesc, valuebox)
+ return destbox.op_setfield(jitstate, fielddesc, valuebox)
def ll_gengetsubstruct(jitstate, fielddesc, argbox):
if argbox.is_constant():
res = getattr(rvalue.ll_getvalue(argbox, fielddesc.PTRTYPE),
fielddesc.fieldname)
return rvalue.ll_fromvalue(jitstate, res)
- assert isinstance(argbox, rvalue.PtrRedBox)
- if argbox.content is None:
- gv_ptr = argbox.getgenvar(jitstate.curbuilder)
- return fielddesc.generate_getsubstruct(jitstate.curbuilder, gv_ptr)
- else:
- return argbox.content.op_getsubstruct(jitstate, fielddesc)
-
+ return argbox.op_getsubstruct(jitstate, fielddesc)
def ll_gengetarrayitem(jitstate, fielddesc, argbox, indexbox):
if fielddesc.immutable and argbox.is_constant() and indexbox.is_constant():
Modified: pypy/dist/pypy/jit/timeshifter/rtyper.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/rtyper.py (original)
+++ pypy/dist/pypy/jit/timeshifter/rtyper.py Mon Oct 9 20:45:39 2006
@@ -409,14 +409,15 @@
v_argbox, c_fieldname = hop.inputargs(self.getredrepr(PTRTYPE),
green_void_repr)
+ v_argbox = hop.llops.as_ptrredbox(v_argbox)
structdesc = rcontainer.StructTypeDesc(self.RGenOp, PTRTYPE.TO)
fielddesc = structdesc.getfielddesc(c_fieldname.value)
c_fielddesc = inputconst(lltype.Void, fielddesc)
s_fielddesc = ts.rtyper.annotator.bookkeeper.immutablevalue(fielddesc)
v_jitstate = hop.llops.getjitstate()
return hop.llops.genmixlevelhelpercall(rtimeshift.ll_gengetfield,
- [ts.s_JITState, s_fielddesc, ts.s_RedBox],
- [v_jitstate, c_fielddesc, v_argbox ],
+ [ts.s_JITState, s_fielddesc, ts.s_PtrRedBox],
+ [v_jitstate, c_fielddesc, v_argbox ],
ts.s_RedBox)
def translate_op_getarrayitem(self, hop):
@@ -486,14 +487,15 @@
green_void_repr,
self.getredrepr(VALUETYPE)
)
+ v_destbox = hop.llops.as_ptrredbox(v_destbox)
structdesc = rcontainer.StructTypeDesc(self.RGenOp, PTRTYPE.TO)
fielddesc = structdesc.getfielddesc(c_fieldname.value)
c_fielddesc = inputconst(lltype.Void, fielddesc)
s_fielddesc = ts.rtyper.annotator.bookkeeper.immutablevalue(fielddesc)
v_jitstate = hop.llops.getjitstate()
return hop.llops.genmixlevelhelpercall(rtimeshift.ll_gensetfield,
- [ts.s_JITState, s_fielddesc, ts.s_RedBox, ts.s_RedBox],
- [v_jitstate, c_fielddesc, v_destbox, v_valuebox],
+ [ts.s_JITState, s_fielddesc, ts.s_PtrRedBox, ts.s_RedBox],
+ [v_jitstate, c_fielddesc, v_destbox, v_valuebox],
annmodel.s_None)
def translate_op_setarrayitem(self, hop):
@@ -519,14 +521,15 @@
PTRTYPE = originalconcretetype(hop.args_s[0])
v_argbox, c_fieldname = hop.inputargs(self.getredrepr(PTRTYPE),
green_void_repr)
+ v_argbox = hop.llops.as_ptrredbox(v_argbox)
fielddesc = rcontainer.NamedFieldDesc(self.RGenOp, PTRTYPE,
c_fieldname.value)
c_fielddesc = inputconst(lltype.Void, fielddesc)
s_fielddesc = ts.rtyper.annotator.bookkeeper.immutablevalue(fielddesc)
v_jitstate = hop.llops.getjitstate()
return hop.llops.genmixlevelhelpercall(rtimeshift.ll_gengetsubstruct,
- [ts.s_JITState, s_fielddesc, ts.s_RedBox],
- [v_jitstate, c_fielddesc, v_argbox ],
+ [ts.s_JITState, s_fielddesc, ts.s_PtrRedBox],
+ [v_jitstate, c_fielddesc, v_argbox ],
ts.s_RedBox)
def translate_op_cast_pointer(self, hop):
@@ -894,8 +897,7 @@
args_s = [ts.s_RedBox] * len(args_v)
if oopspecdesc.is_method:
args_s[0] = ts.s_PtrRedBox # for more precise annotations
- args_v[0] = hop.llops.genop('cast_pointer', [args_v[0]],
- resulttype = ts.r_PtrRedBox.lowleveltype)
+ args_v[0] = hop.llops.as_ptrredbox(args_v[0])
RESULT = originalconcretetype(hop.s_result)
if RESULT is lltype.Void:
s_result = annmodel.s_None
@@ -1033,6 +1035,14 @@
def setjitstate(self, v_newjitstate):
self.genop('setjitstate', [v_newjitstate])
+ def as_redbox(self, v_ptrredbox):
+ return self.genop('cast_pointer', [v_ptrredbox],
+ resulttype = self.hrtyper.r_RedBox)
+
+ def as_ptrredbox(self, v_redbox):
+ return self.genop('cast_pointer', [v_redbox],
+ resulttype = self.hrtyper.r_PtrRedBox)
+
# ____________________________________________________________
class __extend__(pairtype(HintTypeSystem, hintmodel.SomeLLAbstractValue)):
@@ -1120,8 +1130,7 @@
self.typedesc = rcontainer.StructTypeDesc(ts.RGenOp, T)
v_ptrbox = hop.llops.genmixlevelhelpercall(self.typedesc.ll_factory,
[], [], ts.s_PtrRedBox)
- return hop.llops.genop('cast_pointer', [v_ptrbox], resulttype=
- ts.r_RedBox)
+ return hop.llops.as_redbox(v_ptrbox)
class BlueRepr(Repr):
Modified: pypy/dist/pypy/jit/timeshifter/rvalue.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/rvalue.py (original)
+++ pypy/dist/pypy/jit/timeshifter/rvalue.py Mon Oct 9 20:45:39 2006
@@ -178,6 +178,41 @@
else:
return RedBox.__repr__(self)
+ def op_getfield(self, jitstate, fielddesc):
+ if self.content is not None:
+ box = self.content.op_getfield(jitstate, fielddesc)
+ if box is not None:
+ return box
+ gv_ptr = self.getgenvar(jitstate.curbuilder)
+ box = fielddesc.generate_get(jitstate.curbuilder, gv_ptr)
+ if fielddesc.immutable:
+ self.remember_field(fielddesc, box)
+ return box
+
+ def op_setfield(self, jitstate, fielddesc, valuebox):
+ gv_ptr = self.genvar
+ if gv_ptr:
+ fielddesc.generate_set(jitstate.curbuilder, gv_ptr, valuebox)
+ else:
+ assert self.content is not None
+ self.content.op_setfield(jitstate, fielddesc, valuebox)
+
+ def op_getsubstruct(self, jitstate, fielddesc):
+ gv_ptr = self.genvar
+ if gv_ptr:
+ return fielddesc.generate_getsubstruct(jitstate.curbuilder, gv_ptr)
+ else:
+ assert self.content is not None
+ return self.content.op_getsubstruct(jitstate, fielddesc)
+
+ def remember_field(self, fielddesc, box):
+ if self.genvar.is_const:
+ return # no point in remembering field then
+ if self.content is None:
+ from pypy.jit.timeshifter import rcontainer
+ self.content = rcontainer.PartialDataStruct()
+ self.content.remember_field(fielddesc, box)
+
def copy(self, memo):
boxmemo = memo.boxes
try:
@@ -207,7 +242,8 @@
try:
return boxmemo[self]
except KeyError:
- if self.content:
+ if not self.genvar:
+ assert self.content is not None
result = FrozenPtrVirtual(self.kind)
boxmemo[self] = result
result.fz_content = self.content.freeze(memo)
@@ -216,6 +252,12 @@
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
boxmemo[self] = result
return result
@@ -226,11 +268,17 @@
assert self.genvar
return self.genvar
+## def forcevar(self, builder, memo):
+## RedBox.forcevar(self, builder, memo)
+## # if self.content is still there, it's a PartialDataStruct
+## # - for now, we always remove it in this situation
+## self.content = None
+
def enter_block(self, incoming, memo):
+ if self.genvar:
+ RedBox.enter_block(self, incoming, memo)
if self.content:
self.content.enter_block(incoming, memo)
- else:
- RedBox.enter_block(self, incoming, memo)
# ____________________________________________________________
@@ -378,12 +426,28 @@
def exactmatch(self, box, outgoingvarboxes, memo):
assert isinstance(box, PtrRedBox)
- if box.content is None:
+ if box.genvar:
outgoingvarboxes.append(box)
return False
else:
+ assert box.content is not None
return self.fz_content.exactmatch(box.content, outgoingvarboxes,
memo)
def unfreeze(self, incomingvarboxes, memo):
return self.fz_content.unfreeze(incomingvarboxes, memo)
+
+
+##class FrozenPtrVarWithData(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
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 Mon Oct 9 20:45:39 2006
@@ -43,8 +43,6 @@
self.check_insns(int_add=10, int_mul=0)
def test_multiple_portal_calls(self):
- # so far, crashes when we call timeshift() multiple times
- py.test.skip("in-progress")
def ll_function(n):
k = n
if k > 5:
@@ -244,7 +242,6 @@
def test_method_call_promote(self):
- py.test.skip("in-progress")
class Base(object):
pass
class Int(Base):
@@ -276,8 +273,8 @@
res = self.timeshift(ll_function, [5], [], policy=P_NOVIRTUAL)
assert res == 10
- self.check_insns(indirect_call=0, direct_call=1)
+ self.check_insns(indirect_call=0)
res = self.timeshift(ll_function, [0], [], policy=P_NOVIRTUAL)
assert res == ord('2')
- self.check_insns(indirect_call=0, direct_call=1)
+ self.check_insns(indirect_call=0)
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 Mon Oct 9 20:45:39 2006
@@ -80,6 +80,10 @@
key = ll_function, inline, policy
try:
cache, argtypes = self._cache[key]
+ # XXX TEMPORARY: for now, caching doesn't work in the presence
+ # of global caches
+ if getattr(ll_function, '_global_merge_points_', False):
+ raise KeyError
except KeyError:
pass
else:
More information about the Pypy-commit
mailing list