[pypy-svn] r32683 - in pypy/branch/jit-promotion: . pypy/jit/codegen pypy/jit/codegen/llgraph pypy/jit/hintannotator pypy/jit/timeshifter pypy/jit/timeshifter/test pypy/rpython pypy/rpython/lltypesystem pypy/rpython/test
arigo at codespeak.net
arigo at codespeak.net
Wed Sep 27 21:21:53 CEST 2006
Author: arigo
Date: Wed Sep 27 21:21:50 2006
New Revision: 32683
Added:
pypy/branch/jit-promotion/
- copied from r32681, pypy/dist/
pypy/branch/jit-promotion/pypy/jit/timeshifter/test/test_promotion.py (contents, props changed)
pypy/branch/jit-promotion/pypy/rpython/annlowlevel.py
- copied unchanged from r32682, pypy/dist/pypy/rpython/annlowlevel.py
pypy/branch/jit-promotion/pypy/rpython/rmodel.py
- copied unchanged from r32682, pypy/dist/pypy/rpython/rmodel.py
pypy/branch/jit-promotion/pypy/rpython/test/test_llann.py
- copied unchanged from r32682, pypy/dist/pypy/rpython/test/test_llann.py
Modified:
pypy/branch/jit-promotion/pypy/jit/codegen/llgraph/llimpl.py
pypy/branch/jit-promotion/pypy/jit/codegen/llgraph/rgenop.py
pypy/branch/jit-promotion/pypy/jit/codegen/model.py
pypy/branch/jit-promotion/pypy/jit/hintannotator/model.py
pypy/branch/jit-promotion/pypy/jit/timeshifter/rcontainer.py
pypy/branch/jit-promotion/pypy/jit/timeshifter/rtimeshift.py
pypy/branch/jit-promotion/pypy/jit/timeshifter/rtyper.py
pypy/branch/jit-promotion/pypy/jit/timeshifter/rvalue.py
pypy/branch/jit-promotion/pypy/jit/timeshifter/test/test_timeshift.py
pypy/branch/jit-promotion/pypy/jit/timeshifter/transform.py
pypy/branch/jit-promotion/pypy/rpython/lltypesystem/lloperation.py
Log:
(arre, pedronis, arigo)
Intermediate check-in to share this big batch of changes: see
test_promotion for the goal.
Modified: pypy/branch/jit-promotion/pypy/jit/codegen/llgraph/llimpl.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/llgraph/llimpl.py (original)
+++ pypy/branch/jit-promotion/pypy/jit/codegen/llgraph/llimpl.py Wed Sep 27 21:21:50 2006
@@ -125,14 +125,15 @@
result = op.fold(*examples)
return lltype.typeOf(result)
-def gencallableconst(name, targetcontainer, gv_FUNCTYPE):
+def gencallableconst(name, targetcontainer, returncontainer, gv_FUNCTYPE):
# 'name' is just a way to track things
if not isinstance(name, str):
name = LLSupport.from_rstr(name)
target = from_opaque_object(targetcontainer.obj)
+ returnblock = from_opaque_object(returncontainer.obj)
FUNCTYPE = from_opaque_object(gv_FUNCTYPE).value
fptr = lltype.functionptr(FUNCTYPE, name,
- graph=_buildgraph(target, FUNCTYPE))
+ graph=_buildgraph(target, returnblock, FUNCTYPE))
return genconst(fptr)
def genconst(llvalue):
@@ -202,6 +203,29 @@
return pseudotuple(to_opaque_object(false_link),
to_opaque_object(true_link))
+def closeblockswitch(blockcontainer, exitswitch):
+ block = from_opaque_object(blockcontainer.obj)
+ exitswitch = from_opaque_object(exitswitch)
+ assert isinstance(exitswitch, flowmodel.Variable)
+ block.exitswitch = exitswitch
+ default_link = flowmodel.Link([], None)
+ default_link.exitcase = "default"
+ default_link.llexitcase = None
+ block.closeblock(default_link)
+ return to_opaque_object(default_link)
+
+def add_case(blockcontainer, exitcase):
+ block = from_opaque_object(blockcontainer.obj)
+ exitcase = from_opaque_object(exitcase)
+ assert isinstance(exitcase, flowmodel.Constant)
+ assert isinstance(block.exitswitch, Variable)
+ case_link = flowmodel.Link([], None)
+ case_link.exitcase = exitcase.value
+ case_link.llexitcase = exitcase.value
+ exits = block.exits[:-1] + (case_link,) + block.exits[-1:]
+ block.recloseblock(*exits)
+ return to_opaque_object(case_link)
+
class pseudotuple(object):
# something that looks both like a hl and a ll tuple
def __init__(self, *items):
@@ -239,32 +263,32 @@
vars = _inputvars(vars)
_closelink(link, vars, targetblock)
-def closereturnlink(link, returnvar):
- returnvar = from_opaque_object(returnvar)
- link = from_opaque_object(link)
- v = flowmodel.Variable()
- v.concretetype = returnvar.concretetype
- pseudoreturnblock = flowmodel.Block([v])
- pseudoreturnblock.operations = ()
- _closelink(link, [returnvar], pseudoreturnblock)
-
-def _patchgraph(graph, RESULT):
- returntype = None
- links = []
- for link in graph.iterlinks():
- if link.target.operations == ():
- assert len(link.args) == 1 # for now
- if returntype is None:
- returntype = link.target.inputargs[0].concretetype
- else:
- assert returntype == link.target.inputargs[0].concretetype
- links.append(link)
- if returntype is None:
- returntype = lltype.Void
- graph.returnblock.inputargs[0].concretetype = RESULT
- targetblock = casting_bridge([returntype], [RESULT], graph.returnblock)
- for link in links:
- link.target = targetblock
+##def closereturnlink(link, returnvar):
+## returnvar = from_opaque_object(returnvar)
+## link = from_opaque_object(link)
+## v = flowmodel.Variable()
+## v.concretetype = returnvar.concretetype
+## pseudoreturnblock = flowmodel.Block([v])
+## pseudoreturnblock.operations = ()
+## _closelink(link, [returnvar], pseudoreturnblock)
+
+##def _patchgraph(graph, RESULT):
+## returntype = None
+## links = []
+## for link in graph.iterlinks():
+## if link.target.operations == ():
+## assert len(link.args) == 1 # for now
+## if returntype is None:
+## returntype = link.target.inputargs[0].concretetype
+## else:
+## assert returntype == link.target.inputargs[0].concretetype
+## links.append(link)
+## if returntype is None:
+## returntype = lltype.Void
+## graph.returnblock.inputargs[0].concretetype = RESULT
+## targetblock = casting_bridge([returntype], [RESULT], graph.returnblock)
+## for link in links:
+## link.target = targetblock
class PseudoRTyper(object):
def __init__(self):
@@ -297,20 +321,28 @@
else:
return target
-def _buildgraph(block, FUNCTYPE):
+def _buildgraph(block, existingreturnblock, FUNCTYPE):
ARGS = [v.concretetype for v in block.inputargs]
startblock =casting_bridge(FUNCTYPE.ARGS, ARGS, block)
graph = flowmodel.FunctionGraph('generated', startblock)
- _patchgraph(graph, FUNCTYPE.RESULT)
+
+ returntype = existingreturnblock.inputargs[0].concretetype
+ RESULT = FUNCTYPE.RESULT
+ graph.returnblock.inputargs[0].concretetype = RESULT
+ prereturnblock = casting_bridge([returntype], [RESULT], graph.returnblock)
+ existingreturnblock.closeblock(flowmodel.Link(
+ [existingreturnblock.inputargs[0]],
+ prereturnblock))
flowmodel.checkgraph(graph)
eliminate_empty_blocks(graph)
join_blocks(graph)
graph.rgenop = True
return graph
-def buildgraph(blockcontainer, FUNCTYPE):
+def buildgraph(blockcontainer, returncontainer, FUNCTYPE):
block = from_opaque_object(blockcontainer.obj)
- return _buildgraph(block, FUNCTYPE)
+ returnblock = from_opaque_object(returncontainer.obj)
+ return _buildgraph(block, returnblock, FUNCTYPE)
def testgengraph(gengraph, args, viewbefore=False, executor=LLInterpreter):
if viewbefore:
@@ -318,9 +350,9 @@
llinterp = executor(PseudoRTyper())
return llinterp.eval_graph(gengraph, args)
-def runblock(blockcontainer, FUNCTYPE, args,
+def runblock(blockcontainer, returncontainer, FUNCTYPE, args,
viewbefore=False, executor=LLInterpreter):
- graph = buildgraph(blockcontainer, FUNCTYPE)
+ graph = buildgraph(blockcontainer, returncontainer, FUNCTYPE)
return testgengraph(graph, args, viewbefore, executor)
# ____________________________________________________________
@@ -396,8 +428,10 @@
setannotation(isconst, annmodel.SomeBool())
setannotation(closeblock1, s_Link)
setannotation(closeblock2, s_LinkPair)
+setannotation(closeblockswitch, s_Link)
+setannotation(add_case, s_Link)
setannotation(closelink, None)
-setannotation(closereturnlink, None)
+#setannotation(closereturnlink, None)
setannotation(isptrtype, annmodel.SomeBool())
Modified: pypy/branch/jit-promotion/pypy/jit/codegen/llgraph/rgenop.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/llgraph/rgenop.py (original)
+++ pypy/branch/jit-promotion/pypy/jit/codegen/llgraph/rgenop.py Wed Sep 27 21:21:50 2006
@@ -1,7 +1,7 @@
from pypy.rpython.objectmodel import specialize
from pypy.rpython.lltypesystem import lltype
from pypy.jit.codegen.model import AbstractRGenOp, CodeGenBlock, CodeGenerator
-from pypy.jit.codegen.model import GenVar, GenConst
+from pypy.jit.codegen.model import GenVar, GenConst, CodeGenSwitch
from pypy.jit.codegen.llgraph import llimpl
from pypy.rpython.lltypesystem.rclass import fishllattr
@@ -30,14 +30,29 @@
class LLBlock(CodeGenBlock):
- def __init__(self, b):
+ def __init__(self, b, g):
self.b = b
+ self.g = g
+
+class LLFlexSwitch(CodeGenSwitch):
+
+ def __init__(self, b, g):
+ self.b = b
+ self.g = g
+
+ def add_case(self, gv_case):
+ l_case = llimpl.add_case(self.b, gv_case.v)
+ builder = LLBuilder(self.g)
+ builder.lnk = l_case
+ return builder
+
class LLBuilder(CodeGenerator):
lnk = llimpl.nulllink
- def __init__(self):
+ def __init__(self, g):
self.rgenop = rgenop
+ self.g = g
@specialize.arg(1)
def genop1(self, opname, gv_arg):
@@ -114,7 +129,7 @@
llimpl.closelink(lnk, args_gv, self.b)
for i in range(len(args_gv)):
args_gv[i] = newb_args_gv[i]
- return LLBlock(self.b)
+ return LLBlock(self.b, self.g)
def finish_and_goto(self, args_gv, targetblock):
lnk = self.lnk or llimpl.closeblock1(self.b)
@@ -122,15 +137,13 @@
llimpl.closelink(lnk, args_gv, targetblock.b)
def finish_and_return(self, sigtoken, gv_returnvar):
- lnk = self.lnk or llimpl.closeblock1(self.b)
- self.lnk = llimpl.nulllink
- llimpl.closereturnlink(lnk,
- (gv_returnvar or gv_dummy_placeholder).v)
+ gv_returnvar = gv_returnvar or gv_dummy_placeholder
+ self.finish_and_goto([gv_returnvar], LLBlock(self.g, self.g))
def jump_if_true(self, gv_cond):
l_false, l_true = llimpl.closeblock2(self.b, gv_cond.v)
self.b = llimpl.nullblock
- later_builder = LLBuilder()
+ later_builder = LLBuilder(self.g)
later_builder.lnk = l_true
self.lnk = l_false
return later_builder
@@ -138,24 +151,35 @@
def jump_if_false(self, gv_cond):
l_false, l_true = llimpl.closeblock2(self.b, gv_cond.v)
self.b = llimpl.nullblock
- later_builder = LLBuilder()
+ later_builder = LLBuilder(self.g)
later_builder.lnk = l_false
self.lnk = l_true
return later_builder
+ def flexswitch(self, gv_switchvar):
+ l_default = llimpl.closeblockswitch(self.b, gv_switchvar.v)
+ flexswitch = LLFlexSwitch(self.b, self.g)
+ self.b = llimpl.nullblock
+ self.lnk = l_default
+ return flexswitch
+
class RGenOp(AbstractRGenOp):
gv_Void = gv_Void
def newgraph(self, (ARGS_gv, gv_RESULT, gv_FUNCTYPE)):
- builder = LLBuilder()
+ returnblock = llimpl.newblock()
+ llimpl.geninputarg(returnblock, gv_RESULT.v)
+ g = returnblock # for now
+ builder = LLBuilder(g)
inputargs_gv = builder._newblock(ARGS_gv)
- return builder, LLBlock(builder.b), inputargs_gv
+ return builder, LLBlock(builder.b, builder.g), inputargs_gv
def gencallableconst(self, (ARGS_gv, gv_RESULT, gv_FUNCTYPE), name,
entrypoint):
return LLConst(llimpl.gencallableconst(name, entrypoint.b,
+ entrypoint.g,
gv_FUNCTYPE.v))
@staticmethod
@@ -201,6 +225,11 @@
constPrebuiltGlobal = genconst
+ def replay(self, block, kinds):
+ builder = LLBuilder(block.g)
+ args_gv = builder._newblock(kinds)
+ return builder, args_gv
+
# not RPython, just for debugging. Specific to llgraph.
@staticmethod
def reveal(gv):
@@ -210,15 +239,6 @@
v = fishllattr(gv, 'v')
return llimpl.reveal(v)
- # Builds a real flow.model.FunctionGraph. Specific to llgraph.
- @staticmethod
- def buildgraph(block, FUNCTYPE):
- if hasattr(block, 'b'):
- b = block.b
- else:
- b = fishllattr(block, 'b')
- return llimpl.buildgraph(b, FUNCTYPE)
-
def _freeze_(self):
return True # no real point in using a full class in llgraph
Modified: pypy/branch/jit-promotion/pypy/jit/codegen/model.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/model.py (original)
+++ pypy/branch/jit-promotion/pypy/jit/codegen/model.py Wed Sep 27 21:21:50 2006
@@ -23,3 +23,7 @@
class AbstractRGenOp(object):
pass
+
+
+class CodeGenSwitch(object):
+ pass
Modified: pypy/branch/jit-promotion/pypy/jit/hintannotator/model.py
==============================================================================
--- pypy/dist/pypy/jit/hintannotator/model.py (original)
+++ pypy/branch/jit-promotion/pypy/jit/hintannotator/model.py Wed Sep 27 21:21:50 2006
@@ -258,6 +258,10 @@
# turn a variable to a constant
origin = getbookkeeper().myorigin()
return SomeLLAbstractConstant(hs_v1.concretetype, {origin: True})
+ if hs_flags.const.get('promote', False):
+ hs_concrete = SomeLLAbstractConstant(hs_v1.concretetype, {})
+ hs_concrete.eager_concrete = True
+ return hs_concrete
def getfield(hs_v1, hs_fieldname):
S = hs_v1.concretetype.TO
@@ -311,8 +315,6 @@
return hs_c1
def hint(hs_c1, hs_flags):
- if hs_flags.const.get('variable', False): # only for testing purposes!!!
- return SomeLLAbstractVariable(hs_c1.concretetype)
if hs_flags.const.get('concrete', False):
for o in hs_c1.origins:
o.set_fixed()
@@ -322,6 +324,7 @@
if hs_flags.const.get('forget', False):
assert isinstance(hs_c1, SomeLLAbstractConstant)
return reorigin(hs_c1)
+ return SomeLLAbstractValue.hint(hs_c1, hs_flags)
def direct_call(hs_f1, *args_hs):
bookkeeper = getbookkeeper()
Modified: pypy/branch/jit-promotion/pypy/jit/timeshifter/rcontainer.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/rcontainer.py (original)
+++ pypy/branch/jit-promotion/pypy/jit/timeshifter/rcontainer.py Wed Sep 27 21:21:50 2006
@@ -1,5 +1,6 @@
import operator
from pypy.rpython.lltypesystem import lltype
+from pypy.rpython.annlowlevel import cachedtype
from pypy.jit.timeshifter import rvalue
class AbstractContainer(object):
@@ -14,27 +15,8 @@
def op_getsubstruct(self, jitstate, fielddesc):
raise NotImplementedError
-
# ____________________________________________________________
-class cachedtype(type):
- """Metaclass for classes that should only have one instance per
- tuple of arguments given to the constructor."""
-
- def __init__(selfcls, name, bases, dict):
- super(cachedtype, selfcls).__init__(name, bases, dict)
- selfcls._instancecache = {}
-
- def __call__(selfcls, *args):
- d = selfcls._instancecache
- try:
- return d[args]
- except KeyError:
- instance = d[args] = selfcls.__new__(selfcls, *args)
- instance.__init__(*args)
- return instance
-
-
class StructTypeDesc(object):
__metaclass__ = cachedtype
firstsubstructdesc = None
Modified: pypy/branch/jit-promotion/pypy/jit/timeshifter/rtimeshift.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/rtimeshift.py (original)
+++ pypy/branch/jit-promotion/pypy/jit/timeshifter/rtimeshift.py Wed Sep 27 21:21:50 2006
@@ -1,8 +1,12 @@
import operator, weakref
+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.rpython.unroll import unrolling_iterable
+from pypy.rpython.annlowlevel import cachedtype, base_ptr_lltype
+from pypy.rpython.annlowlevel import cast_instance_to_base_ptr
+from pypy.rpython.annlowlevel import cast_base_ptr_to_instance
FOLDABLE_OPS = dict.fromkeys(lloperation.enum_foldable_ops())
@@ -184,7 +188,7 @@
incoming[i].genvar = linkargs[i]
return newblock
-def start_new_block(states_dic, jitstate, key):
+def start_new_block(states_dic, jitstate, key, global_resumer):
memo = rvalue.freeze_memo()
frozen = jitstate.freeze(memo)
memo = rvalue.exactmatch_memo()
@@ -193,11 +197,17 @@
assert res, "exactmatch() failed"
newblock = enter_next_block(jitstate, outgoingvarboxes)
states_dic[key] = frozen, newblock
+ if global_resumer:
+ greens_gv = jitstate.greens
+ rgenop = jitstate.curbuilder.rgenop
+ jitstate.promotion_path = PromotionPathRoot(greens_gv, rgenop,
+ frozen, newblock,
+ global_resumer)
start_new_block._annspecialcase_ = "specialize:arglltype(2)"
-def retrieve_jitstate_for_merge(states_dic, jitstate, key):
+def retrieve_jitstate_for_merge(states_dic, jitstate, key, global_resumer):
if key not in states_dic:
- start_new_block(states_dic, jitstate, key)
+ start_new_block(states_dic, jitstate, key, global_resumer)
return False # continue
frozen, oldblock = states_dic[key]
@@ -219,7 +229,7 @@
box.forcevar(jitstate.curbuilder, replace_memo)
if replace_memo.boxes:
jitstate.replace(replace_memo)
- start_new_block(states_dic, jitstate, key)
+ start_new_block(states_dic, jitstate, key, global_resumer)
return False # continue
retrieve_jitstate_for_merge._annspecialcase_ = "specialize:arglltype(2)"
@@ -304,6 +314,132 @@
##def ll_gvar_from_constant(jitstate, ll_value):
## return jitstate.curbuilder.rgenop.genconst(ll_value)
+
+
+class ResumingInfo(object):
+ def __init__(self, promotion_point, gv_value, path):
+ self.promotion_point = promotion_point
+ self.gv_value = gv_value
+ self.path = path
+
+class PromotionPoint(object):
+ def __init__(self, flexswitch, promotion_path):
+ assert promotion_path is not None
+ self.flexswitch = flexswitch
+ self.promotion_path = promotion_path
+
+class AbstractPromotionPath(object):
+ pass
+
+class PromotionPathRoot(AbstractPromotionPath):
+ def __init__(self, greens_gv, rgenop, frozen, portalblock, global_resumer):
+ self.greens_gv = greens_gv
+ self.rgenop = rgenop
+ self.frozen = frozen
+ self.portalblock = portalblock
+ self.global_resumer = global_resumer
+
+ def follow_path(self, path):
+ return self
+
+ def continue_compilation(self, resuminginfo):
+ incoming = []
+ memo = rvalue.unfreeze_memo()
+ jitstate = self.frozen.unfreeze(incoming, memo)
+ kinds = [box.kind for box in incoming]
+ builder, vars_gv = self.rgenop.replay(self.portalblock, kinds)
+ for i in range(len(incoming)):
+ incoming[i].genvar = vars_gv[i]
+ jitstate.curbuilder = builder
+ jitstate.greens = self.greens_gv
+ jitstate.resuming = resuminginfo
+ assert jitstate.frame.backframe is None
+ self.global_resumer(jitstate)
+
+class PromotionPathNode(AbstractPromotionPath):
+ def __init__(self, next):
+ self.next = next
+ def follow_path(self, path):
+ path.append(self.direct)
+ return self.next.follow_path(path)
+
+class PromotionPathDirect(PromotionPathNode):
+ direct = True
+
+class PromotionPathIndirect(PromotionPathNode):
+ direct = False
+
+def ll_continue_compilation(promotion_point_ptr, value):
+ try:
+ promotion_point = cast_base_ptr_to_instance(PromotionPoint,
+ promotion_point_ptr)
+ path = []
+ root = promotion_point.promotion_path.follow_path(path)
+ gv_value = root.rgenop.genconst(value)
+ resuminginfo = ResumingInfo(promotion_point, gv_value, path)
+ root.continue_compilation(resuminginfo)
+ except Exception, e:
+ llop.debug_fatalerror(lltype.Void, "compilation-time error", e)
+
+class PromotionDesc:
+ __metatype__ = cachedtype
+
+ def __init__(self, ERASED, hrtyper):
+## (s_PromotionPoint,
+## r_PromotionPoint) = hrtyper.s_r_instanceof(PromotionPoint)
+ fnptr = hrtyper.annhelper.delayedfunction(
+ ll_continue_compilation,
+ [annmodel.SomePtr(base_ptr_lltype()),
+ annmodel.lltype_to_annotation(ERASED)],
+ annmodel.s_None, needtype=True)
+ RGenOp = hrtyper.RGenOp
+ self.gv_continue_compilation = RGenOp.constPrebuiltGlobal(fnptr)
+ self.sigtoken = RGenOp.sigToken(lltype.typeOf(fnptr).TO)
+## self.PROMOTION_POINT = r_PromotionPoint.lowleveltype
+
+ def _freeze_(self):
+ return True
+
+def ll_promote(jitstate, box, promotiondesc):
+ if box.is_constant():
+ save_greens(jitstate, box.genvar)
+ return False
+ else:
+ incoming = []
+ memo = rvalue.enter_block_memo()
+ jitstate.enter_block(incoming, memo)
+ switchblock = enter_next_block(jitstate, incoming)
+
+ if jitstate.resuming is None:
+ builder = jitstate.curbuilder
+ flexswitch = builder.flexswitch(box.getgenvar(builder))
+ # default case of the switch:
+ enter_block(jitstate)
+ pm = PromotionPoint(flexswitch, jitstate.promotion_path)
+ ll_pm = cast_instance_to_base_ptr(pm)
+ gv_pm = builder.rgenop.genconst(ll_pm)
+ builder.genop_call(promotiondesc.sigtoken,
+ promotiondesc.gv_continue_compilation,
+ [gv_pm, box.getgenvar(builder)])
+ linkargs = []
+ for box in incoming:
+ linkargs.append(box.getgenvar(builder))
+ builder.finish_and_goto(linkargs, switchblock)
+ return True
+ else:
+ assert jitstate.promotion_path is None
+ resuming = jitstate.resuming
+ assert len(resuming.path) == 0
+ pm = resuming.promotion_point
+ newbuilder = pm.flexswitch.add_case(resuming.gv_value)
+
+ jitstate.resuming = None
+ jitstate.promotion_path = pm.promotion_path
+ jitstate.curbuilder = newbuilder
+ enter_block(jitstate)
+ save_greens(jitstate, resuming.gv_value)
+ return False
+
# ____________________________________________________________
class BaseDispatchQueue(object):
@@ -346,6 +482,18 @@
assert vframe.backframe is None
return fullmatch
+ def unfreeze(self, incomingvarboxes, memo):
+ local_boxes = []
+ for fzbox in self.fz_local_boxes:
+ local_boxes.append(fzbox.unfreeze(incomingvarboxes, memo))
+ if self.fz_backframe is not None:
+ backframe = self.fz_backframe.unfreeze(incomingvarboxes, memo)
+ else:
+ backframe = None
+ vframe = VirtualFrame(backframe, BaseDispatchQueue())
+ vframe.local_boxes = local_boxes
+ return vframe
+
class FrozenJITState(object):
#fz_frame = ... set by freeze()
@@ -368,6 +516,12 @@
fullmatch = False
return fullmatch
+ def unfreeze(self, incomingvarboxes, memo):
+ frame = self.fz_frame .unfreeze(incomingvarboxes, memo)
+ exc_type_box = self.fz_exc_type_box .unfreeze(incomingvarboxes, memo)
+ exc_value_box = self.fz_exc_value_box.unfreeze(incomingvarboxes, memo)
+ return JITState(None, frame, exc_type_box, exc_value_box)
+
class VirtualFrame(object):
@@ -410,15 +564,17 @@
class JITState(object):
returnbox = None
next = None # for linked lists
+ resuming = None # or a ResumingInfo
def __init__(self, builder, frame, exc_type_box, exc_value_box,
- resumepoint=-1, newgreens=[]):
+ resumepoint=-1, newgreens=[], promotion_path=None):
self.curbuilder = builder
self.frame = frame
self.exc_type_box = exc_type_box
self.exc_value_box = exc_value_box
self.resumepoint = resumepoint
self.greens = newgreens
+ self.promotion_path = promotion_path
def split(self, newbuilder, newresumepoint, newgreens):
memo = rvalue.copy_memo()
@@ -427,7 +583,9 @@
self.exc_type_box .copy(memo),
self.exc_value_box.copy(memo),
newresumepoint,
- newgreens)
+ newgreens,
+ PromotionPathIndirect(self.promotion_path))
+ self.promotion_path = PromotionPathDirect(self.promotion_path)
# add the later_jitstate to the chain of pending-for-dispatch_next()
dispatch_queue = self.frame.dispatch_queue
later_jitstate.next = dispatch_queue.split_chain
@@ -456,6 +614,9 @@
enter_graph._annspecialcase_ = 'specialize:arg(1)'
# XXX is that too many specializations? ^^^
+class CompilationInterrupted(Exception):
+ pass
+
def merge_returning_jitstates(jitstate):
return_chain = jitstate.frame.dispatch_queue.return_chain
return_cache = {}
@@ -463,17 +624,18 @@
while return_chain is not None:
jitstate = return_chain
return_chain = return_chain.next
- res = retrieve_jitstate_for_merge(return_cache, jitstate, ())
+ res = retrieve_jitstate_for_merge(return_cache, jitstate, (), None)
if res is False: # not finished
jitstate.next = still_pending
still_pending = jitstate
- assert still_pending is not None
+ if still_pending is None:
+ raise CompilationInterrupted
most_general_jitstate = still_pending
still_pending = still_pending.next
while still_pending is not None:
jitstate = still_pending
still_pending = still_pending.next
- res = retrieve_jitstate_for_merge(return_cache, jitstate, ())
+ res = retrieve_jitstate_for_merge(return_cache, jitstate, (), None)
assert res is True # finished
return most_general_jitstate
Modified: pypy/branch/jit-promotion/pypy/jit/timeshifter/rtyper.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/rtyper.py (original)
+++ pypy/branch/jit-promotion/pypy/jit/timeshifter/rtyper.py Wed Sep 27 21:21:50 2006
@@ -191,6 +191,14 @@
# the graph is transformed already
return self.annotator.bookkeeper.tsgraphsigs[tsgraph]
+ def get_residual_functype(self, tsgraph):
+ ha = self.annotator
+ args_hs, hs_res = self.get_sig_hs(ha.translator.graphs[0])
+ RESTYPE = originalconcretetype(hs_res)
+ ARGS = [originalconcretetype(hs_arg) for hs_arg in args_hs
+ if not hs_arg.is_green()]
+ return lltype.FuncType(ARGS, RESTYPE)
+
def make_new_lloplist(self, block):
return HintLowLevelOpList(self)
@@ -230,8 +238,11 @@
try:
return self.dispatchsubclasses[mergepointfamily]
except KeyError:
- attrnames = mergepointfamily.getattrnames()
- subclass = rtimeshift.build_dispatch_subclass(attrnames)
+ if mergepointfamily.is_global:
+ subclass = rtimeshift.BaseDispatchQueue
+ else:
+ attrnames = mergepointfamily.getattrnames()
+ subclass = rtimeshift.build_dispatch_subclass(attrnames)
self.dispatchsubclasses[mergepointfamily] = subclass
return subclass
@@ -357,24 +368,6 @@
[c_opdesc, v_jitstate] + args_v,
ts.s_RedBox)
- def translate_op_hint(self, hop):
- # don't try to generate hint operations, just discard them
- hints = hop.args_v[-1].value
- if hints.get('forget', False):
- T = originalconcretetype(hop.args_s[0])
- v_redbox = hop.inputarg(self.getredrepr(T), arg=0)
- assert isinstance(hop.r_result, GreenRepr)
- ts = self
- c_T = hop.inputconst(lltype.Void, T)
- s_T = ts.rtyper.annotator.bookkeeper.immutablevalue(T)
- s_res = annmodel.lltype_to_annotation(T)
- return hop.llops.genmixlevelhelpercall(rvalue.ll_getvalue,
- [ts.s_RedBox, s_T],
- [v_redbox, c_T],
- s_res)
-
- return hop.inputarg(hop.r_result, arg=0)
-
def translate_op_debug_log_exc(self, hop): # don't timeshift debug_log_exc
pass
@@ -738,17 +731,25 @@
args_s, args_v,
annmodel.s_None)
- def translate_op_merge_point(self, hop):
+ def translate_op_merge_point(self, hop, global_resumer=None):
mpfamily = hop.args_v[0].value
attrname = hop.args_v[1].value
DispatchQueueSubclass = self.get_dispatch_subclass(mpfamily)
- def merge_point(jitstate, *key):
- dispatch_queue = jitstate.frame.dispatch_queue
- assert isinstance(dispatch_queue, DispatchQueueSubclass)
- states_dic = getattr(dispatch_queue, attrname)
- return rtimeshift.retrieve_jitstate_for_merge(states_dic,
- jitstate, key)
+ if mpfamily.is_global:
+ states_dic = {}
+ def merge_point(jitstate, *key):
+ return rtimeshift.retrieve_jitstate_for_merge(states_dic,
+ jitstate, key,
+ global_resumer)
+ else:
+ def merge_point(jitstate, *key):
+ dispatch_queue = jitstate.frame.dispatch_queue
+ assert isinstance(dispatch_queue, DispatchQueueSubclass)
+ states_dic = getattr(dispatch_queue, attrname)
+ return rtimeshift.retrieve_jitstate_for_merge(states_dic,
+ jitstate, key,
+ global_resumer)
greens_v = []
greens_s = []
@@ -767,6 +768,37 @@
[v_jitstate ] + greens_v,
annmodel.SomeBool())
+ def translate_op_global_merge_point(self, hop):
+ mpfamily = hop.args_v[0].value
+ attrname = hop.args_v[1].value
+ N = mpfamily.resumepoint_after_mergepoint[attrname]
+ tsgraph = mpfamily.tsgraph
+ ts_fnptr = self.gettscallable(tsgraph)
+ TS_FUNC = lltype.typeOf(ts_fnptr)
+ dummy_args = [ARG._defl() for ARG in TS_FUNC.TO.ARGS[1:]]
+ dummy_args = tuple(dummy_args)
+ JITSTATE = self.r_JITState.lowleveltype
+ RESIDUAL_FUNCTYPE = self.get_residual_functype(tsgraph)
+ residualSigToken = self.RGenOp.sigToken(RESIDUAL_FUNCTYPE)
+ ll_finish_jitstate = self.ll_finish_jitstate
+
+ args_s = [self.s_JITState] + [annmodel.lltype_to_annotation(ARG)
+ for ARG in TS_FUNC.TO.ARGS[1:]]
+ s_res = self.s_JITState
+ tsfn = annlowlevel.PseudoHighLevelCallable(ts_fnptr, args_s, s_res)
+
+ def call_for_global_resuming(jitstate):
+ jitstate.resumepoint = N
+ try:
+ finaljitstate = tsfn(jitstate, *dummy_args)
+ except rtimeshift.CompilationInterrupted:
+ pass
+ else:
+ ll_finish_jitstate(finaljitstate, residualSigToken)
+
+ return self.translate_op_merge_point(hop,
+ global_resumer = call_for_global_resuming)
+
def translate_op_save_return(self, hop):
v_jitstate = hop.llops.getjitstate()
return hop.llops.genmixlevelhelpercall(rtimeshift.save_return,
@@ -781,11 +813,29 @@
[v_jitstate ],
self.s_JITState)
hop.llops.setjitstate(v_newjs)
+
+ def translate_op_getresumepoint(self, hop):
+ v_jitstate = hop.llops.getjitstate()
return hop.llops.genmixlevelhelpercall(rtimeshift.getresumepoint,
[self.s_JITState],
- [v_newjs ],
+ [v_jitstate ],
annmodel.SomeInteger())
+ def translate_op_promote(self, hop):
+ TYPE = originalconcretetype(hop.args_s[0])
+ r_arg = self.getredrepr(TYPE)
+ [v_box] = hop.inputargs(r_arg)
+ r_result = self.getgreenrepr(TYPE)
+ ERASED = annmodel.annotation_to_lltype(r_result.erased_annotation())
+ desc = rtimeshift.PromotionDesc(ERASED, self)
+ s_desc = self.rtyper.annotator.bookkeeper.immutablevalue(desc)
+ c_desc = hop.inputconst(lltype.Void, desc)
+ v_jitstate = hop.llops.getjitstate()
+ return hop.llops.genmixlevelhelpercall(rtimeshift.ll_promote,
+ [self.s_JITState, self.s_RedBox, s_desc],
+ [v_jitstate , v_box , c_desc],
+ annmodel.SomeBool())
+
# handling of the various kinds of calls
def translate_op_oopspec_call(self, hop):
Modified: pypy/branch/jit-promotion/pypy/jit/timeshifter/rvalue.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/rvalue.py (original)
+++ pypy/branch/jit-promotion/pypy/jit/timeshifter/rvalue.py Wed Sep 27 21:21:50 2006
@@ -19,6 +19,9 @@
def copy_memo():
return Memo()
+def unfreeze_memo():
+ return Memo()
+
class RedBox(object):
__slots__ = ['kind', 'genvar']
@@ -135,9 +138,9 @@
return memo[self]
except KeyError:
if self.is_constant():
- result = FrozenIntConst(self.genvar)
+ result = FrozenIntConst(self.kind, self.genvar)
else:
- result = FrozenIntVar()
+ result = FrozenIntVar(self.kind)
memo[self] = result
return result
@@ -159,9 +162,9 @@
return memo[self]
except KeyError:
if self.is_constant():
- result = FrozenDoubleConst(self.genvar)
+ result = FrozenDoubleConst(self.kind, self.genvar)
else:
- result = FrozenDoubleVar()
+ result = FrozenDoubleVar(self.kind)
memo[self] = result
return result
@@ -205,14 +208,14 @@
return boxmemo[self]
except KeyError:
if self.content:
- result = FrozenPtrVirtual()
+ result = FrozenPtrVirtual(self.kind)
boxmemo[self] = result
result.fz_content = self.content.freeze(memo)
else:
if self.is_constant():
- result = FrozenPtrConst(self.genvar)
+ result = FrozenPtrConst(self.kind, self.genvar)
else:
- result = FrozenPtrVar()
+ result = FrozenPtrVar(self.kind)
boxmemo[self] = result
return result
@@ -234,11 +237,14 @@
class FrozenValue(object):
"""An abstract value frozen in a saved state.
"""
+ def __init__(self, kind):
+ self.kind = kind
class FrozenIntConst(FrozenValue):
- def __init__(self, gv_const):
+ def __init__(self, kind, gv_const):
+ self.kind = kind
self.gv_const = gv_const
def exactmatch(self, box, outgoingvarboxes, memo):
@@ -250,6 +256,10 @@
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):
@@ -265,10 +275,21 @@
outgoingvarboxes.append(box)
return False
+ def unfreeze(self, incomingvarboxes, memo):
+ memo = memo.boxes
+ if self not in memo:
+ newbox = IntRedBox(self.kind, None)
+ incomingvarboxes.append(newbox)
+ memo[self] = newbox
+ return newbox
+ else:
+ return memo[self]
+
class FrozenDoubleConst(FrozenValue):
- def __init__(self, gv_const):
+ def __init__(self, kind, gv_const):
+ self.kind = kind
self.gv_const = gv_const
def exactmatch(self, box, outgoingvarboxes, memo):
@@ -280,6 +301,9 @@
outgoingvarboxes.append(box)
return False
+ def unfreeze(self, incomingvarboxes, memo):
+ return DoubleRedBox(self.kind, self.gv_const)
+
class FrozenDoubleVar(FrozenValue):
@@ -295,10 +319,21 @@
outgoingvarboxes.append(box)
return False
+ def unfreeze(self, incomingvarboxes, memo):
+ memo = memo.boxes
+ if self not in memo:
+ newbox = DoubleRedBox(self.kind, None)
+ incomingvarboxes.append(newbox)
+ memo[self] = newbox
+ return newbox
+ else:
+ return memo[self]
+
class FrozenPtrConst(FrozenValue):
- def __init__(self, gv_const):
+ def __init__(self, kind, gv_const):
+ self.kind = kind
self.gv_const = gv_const
def exactmatch(self, box, outgoingvarboxes, memo):
@@ -310,6 +345,9 @@
outgoingvarboxes.append(box)
return False
+ def unfreeze(self, incomingvarboxes, memo):
+ return PtrRedBox(self.kind, self.gv_const)
+
class FrozenPtrVar(FrozenValue):
@@ -325,6 +363,16 @@
outgoingvarboxes.append(box)
return False
+ def unfreeze(self, incomingvarboxes, memo):
+ memo = memo.boxes
+ if self not in memo:
+ newbox = PtrRedBox(self.kind, None)
+ incomingvarboxes.append(newbox)
+ memo[self] = newbox
+ return newbox
+ else:
+ return memo[self]
+
class FrozenPtrVirtual(FrozenValue):
@@ -336,3 +384,7 @@
else:
return self.fz_content.exactmatch(box.content, outgoingvarboxes,
memo)
+
+ def unfreeze(self, incomingvarboxes, memo):
+ #return self.fz_content.unfreeze(self.kind, incomingvarboxes, memo)
+ raise NotImplementedError
Added: pypy/branch/jit-promotion/pypy/jit/timeshifter/test/test_promotion.py
==============================================================================
--- (empty file)
+++ pypy/branch/jit-promotion/pypy/jit/timeshifter/test/test_promotion.py Wed Sep 27 21:21:50 2006
@@ -0,0 +1,26 @@
+import py
+from pypy.rpython.lltypesystem import lltype
+from pypy.jit.timeshifter.test.test_timeshift import TimeshiftingTests
+from pypy.rpython.objectmodel import hint
+
+
+class TestPromotion(TimeshiftingTests):
+
+ def test_simple_promotion(self):
+ def ll_two(k):
+ return (k+1)*2
+ def ll_function(n):
+ k = hint(n, promote=True)
+ k = ll_two(k)
+ return hint(k, variable=True)
+ ll_function._global_merge_points_ = True
+
+ # easy case: no promotion needed
+ res = self.timeshift(ll_function, [20], [0])
+ assert res == 42
+ self.check_insns({})
+
+ # the real test: with promotion
+ res = self.timeshift(ll_function, [20], [])
+ assert res == 42
+ self.check_insns(int_add=0, int_mul=0)
Modified: pypy/branch/jit-promotion/pypy/jit/timeshifter/test/test_timeshift.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/test/test_timeshift.py (original)
+++ pypy/branch/jit-promotion/pypy/jit/timeshifter/test/test_timeshift.py Wed Sep 27 21:21:50 2006
@@ -99,8 +99,6 @@
fresh_jitstate = hrtyper.ll_fresh_jitstate
finish_jitstate = hrtyper.ll_finish_jitstate
- args_hs, hs_res = hrtyper.get_sig_hs(ha.translator.graphs[0])
- RESTYPE = originalconcretetype(hs_res)
t = rtyper.annotator.translator
for graph in ha.translator.graphs:
checkgraph(graph)
@@ -119,11 +117,10 @@
assert len(graph1.getargs()) == 1 + len(values)
graph1varargs = graph1.getargs()[1:]
timeshifted_entrypoint_args_s = []
- residual_argtypes = []
argcolors = []
generate_code_args_s = []
- for v, hs_arg, llvalue in zip(graph1varargs, args_hs, values):
+ for v, llvalue in zip(graph1varargs, values):
s_var = annmodel.ll_to_annotation(llvalue)
r = hrtyper.bindingrepr(v)
residual_v = r.residual_values(llvalue)
@@ -133,8 +130,6 @@
else:
color = "red"
assert residual_v == [llvalue], "XXX for now"
- ARGTYPE = originalconcretetype(hs_arg)
- residual_argtypes.append(ARGTYPE)
timeshifted_entrypoint_args_s.append(hrtyper.s_RedBox)
generate_code_args_s.append(annmodel.SomeBool())
argcolors.append(color)
@@ -147,7 +142,7 @@
[hrtyper.s_JITState]
+ timeshifted_entrypoint_args_s,
hrtyper.s_JITState)
- FUNC = lltype.FuncType(residual_argtypes, RESTYPE)
+ FUNC = hrtyper.get_residual_functype(ha.translator.graphs[0])
argcolors = unrolling_iterable(argcolors)
self.argcolors = argcolors
@@ -180,9 +175,13 @@
timeshifted_entrypoint_args += (box,)
top_jitstate = fresh_jitstate(builder)
- top_jitstate = timeshifted_entrypoint(top_jitstate,
+ try:
+ top_jitstate = timeshifted_entrypoint(top_jitstate,
*timeshifted_entrypoint_args)
- finish_jitstate(top_jitstate, sigtoken)
+ except rtimeshift.CompilationInterrupted:
+ pass
+ else:
+ finish_jitstate(top_jitstate, sigtoken)
gv_generated = rgenop.gencallableconst(sigtoken, "generated",
entrypoint)
Modified: pypy/branch/jit-promotion/pypy/jit/timeshifter/transform.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/transform.py (original)
+++ pypy/branch/jit-promotion/pypy/jit/timeshifter/transform.py Wed Sep 27 21:21:50 2006
@@ -13,8 +13,11 @@
class MergePointFamily(object):
- def __init__(self):
+ def __init__(self, tsgraph, is_global=False):
+ self.tsgraph = tsgraph
+ self.is_global = is_global
self.count = 0
+ self.resumepoint_after_mergepoint = {}
def add(self):
result = self.count
self.count += 1
@@ -30,27 +33,32 @@
self.hannotator = hannotator
self.graph = graph
self.graphcolor = self.graph_calling_color(graph)
+ self.global_merge_points = self.graph_global_mps(self.graph)
self.resumepoints = {}
- self.mergepointfamily = MergePointFamily()
+ self.mergepoint_set = {} # set of blocks
+ self.mergepointfamily = MergePointFamily(graph,
+ self.global_merge_points)
self.c_mpfamily = inputconst(lltype.Void, self.mergepointfamily)
self.tsgraphs_seen = []
def transform(self):
- mergepoints = list(self.enumerate_merge_points())
+ self.compute_merge_points()
self.insert_save_return()
self.insert_splits()
- for block in mergepoints:
- self.insert_merge(block)
self.split_after_calls()
- self.insert_dispatcher()
+ self.handle_hints()
+ self.insert_merge_points()
self.insert_enter_graph()
+ self.insert_dispatcher()
self.insert_leave_graph()
- def enumerate_merge_points(self):
+ def compute_merge_points(self):
entrymap = mkentrymap(self.graph)
for block, links in entrymap.items():
if len(links) > 1 and block is not self.graph.returnblock:
- yield block
+ self.mergepoint_set[block] = True
+ if self.global_merge_points:
+ self.mergepoint_set[self.graph.startblock] = True
def graph_calling_color(self, tsgraph):
args_hs, hs_res = self.hannotator.bookkeeper.tsgraphsigs[tsgraph]
@@ -61,6 +69,12 @@
else:
return 'red'
+ def graph_global_mps(self, tsgraph):
+ try:
+ return tsgraph.func._global_merge_points_
+ except AttributeError:
+ return False
+
def timeshifted_graph_of(self, graph, args_v):
bk = self.hannotator.bookkeeper
args_hs = [self.hannotator.binding(v) for v in args_v]
@@ -147,6 +161,13 @@
reds.append(v)
return reds, greens
+ def before_start_block(self):
+ entryblock = self.new_block_before(self.graph.startblock)
+ entryblock.isstartblock = True
+ self.graph.startblock.isstartblock = False
+ self.graph.startblock = entryblock
+ return entryblock
+
def before_return_block(self):
block = self.graph.returnblock
block.operations = []
@@ -239,6 +260,21 @@
def get_resume_point(self, block):
return self.get_resume_point_link(block).exitcase
+ def go_to_if(self, block, target, v_finished_flag):
+ block.exitswitch = v_finished_flag
+ [link_f] = block.exits
+ link_t = Link([self.c_dummy], target)
+ link_f.exitcase = False
+ link_t.exitcase = True
+ block.recloseblock(link_f, link_t)
+
+ def go_to_dispatcher_if(self, block, v_finished_flag):
+ self.go_to_if(block, self.graph.returnblock, v_finished_flag)
+
+ def insert_merge_points(self):
+ for block in self.mergepoint_set:
+ self.insert_merge(block)
+
def insert_merge(self, block):
reds, greens = self.sort_by_color(block.inputargs)
nextblock = self.naive_split_block(block, 0)
@@ -246,15 +282,15 @@
self.genop(block, 'save_locals', reds)
mp = self.mergepointfamily.add()
c_mp = inputconst(lltype.Void, mp)
- v_finished_flag = self.genop(block, 'merge_point',
+ if self.global_merge_points:
+ self.genop(block, 'save_greens', greens)
+ prefix = 'global_'
+ else:
+ prefix = ''
+ v_finished_flag = self.genop(block, '%smerge_point' % (prefix,),
[self.c_mpfamily, c_mp] + greens,
resulttype = lltype.Bool)
- block.exitswitch = v_finished_flag
- [link_f] = block.exits
- link_t = Link([self.c_dummy], self.graph.returnblock)
- link_f.exitcase = False
- link_t.exitcase = True
- block.recloseblock(link_f, link_t)
+ self.go_to_dispatcher_if(block, v_finished_flag)
restoreops = []
mapping = {}
@@ -269,10 +305,26 @@
SSA_to_SSI({block : True, # reachable from outside
nextblock: False}, self.hannotator)
+ if self.global_merge_points:
+ N = self.get_resume_point(nextblock)
+ self.mergepointfamily.resumepoint_after_mergepoint[mp] = N
+
def insert_dispatcher(self):
- if self.resumepoints:
+ if self.global_merge_points or self.resumepoints:
block = self.before_return_block()
- v_switchcase = self.genop(block, 'dispatch_next', [],
+ self.genop(block, 'dispatch_next', [])
+ if self.global_merge_points:
+ block = self.before_return_block()
+ entryblock = self.before_start_block()
+ v_rp = self.genop(entryblock, 'getresumepoint', [],
+ resulttype = lltype.Signed)
+ c_zero = inputconst(lltype.Signed, 0)
+ v_abnormal_entry = self.genop(entryblock, 'int_ge',
+ [v_rp, c_zero],
+ resulttype = lltype.Bool)
+ self.go_to_if(entryblock, block, v_abnormal_entry)
+
+ v_switchcase = self.genop(block, 'getresumepoint', [],
resulttype = lltype.Signed)
block.exitswitch = v_switchcase
defaultlink = block.exits[0]
@@ -297,11 +349,7 @@
self.genop(block, 'save_return', [])
def insert_enter_graph(self):
- entryblock = self.new_block_before(self.graph.startblock)
- entryblock.isstartblock = True
- self.graph.startblock.isstartblock = False
- self.graph.startblock = entryblock
-
+ entryblock = self.before_start_block()
self.genop(entryblock, 'enter_graph', [self.c_mpfamily])
def insert_leave_graph(self):
@@ -363,6 +411,11 @@
def make_call(self, block, op, save_locals_vars, color='red'):
self.genop(block, 'save_locals', save_locals_vars)
targets = dict(self.graphs_from(op))
+ for tsgraph in targets.values():
+ if self.graph_global_mps(tsgraph):
+ # make sure jitstate.resumepoint is set to zero
+ self.genop(block, 'resetresumepoint', [])
+ break
if len(targets) == 1:
[tsgraph] = targets.values()
c_tsgraph = inputconst(lltype.Void, tsgraph)
@@ -475,5 +528,56 @@
link.args = []
link.target = self.get_resume_point_link(nextblock).target
- self.insert_merge(nextblock) # to merge some of the possibly many
- # return jitstates
+ self.mergepoint_set[nextblock] = True # to merge some of the possibly
+ # many return jitstates
+
+ # __________ hints __________
+
+ def handle_hints(self):
+ for block in list(self.graph.iterblocks()):
+ for i in range(len(block.operations)-1, -1, -1):
+ op = block.operations[i]
+ if op.opname == 'hint':
+ hints = op.args[1].value
+ for key, value in hints.items():
+ if value == True:
+ methname = 'handle_%s_hint' % (key,)
+ if hasattr(self, methname):
+ handler = getattr(self, methname)
+ break
+ else:
+ handler = self.handle_default_hint
+ handler(block, i)
+
+ def handle_default_hint(self, block, i):
+ # just discard the hint by default
+ op = block.operations[i]
+ newop = SpaceOperation('same_as', [op.args[0]], op.result)
+ block.operations[i] = newop
+
+ def handle_forget_hint(self, block, i):
+ # a hint for testing only
+ op = block.operations[i]
+ assert self.binding(op.result).is_green()
+ assert not self.binding(op.args[0]).is_green()
+ newop = SpaceOperation('revealconst', [op.args[0]], op.result)
+ block.operations[i] = newop
+
+ def handle_promote_hint(self, block, i):
+ op = block.operations[i]
+ c_zero = inputconst(lltype.Signed, 0)
+ newop = SpaceOperation('restore_green', [c_zero], op.result)
+ block.operations[i] = newop
+
+ link = support.split_block_with_keepalive(block, i,
+ annotator=self.hannotator)
+ nextblock = link.target
+
+ reds, greens = self.sort_by_color(link.args)
+ v_promote = op.args[0]
+ if v_promote not in reds:
+ reds.append(v_promote)
+ self.genop(block, 'save_locals', reds)
+ v_finished_flag = self.genop(block, 'promote', [v_promote],
+ resulttype = lltype.Bool)
+ self.go_to_dispatcher_if(block, v_finished_flag)
Modified: pypy/branch/jit-promotion/pypy/rpython/lltypesystem/lloperation.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/lloperation.py (original)
+++ pypy/branch/jit-promotion/pypy/rpython/lltypesystem/lloperation.py Wed Sep 27 21:21:50 2006
@@ -402,6 +402,7 @@
'debug_pdb': LLOp(),
'debug_log_exc': LLOp(),
'debug_assert': LLOp(canfold=True),
+ 'debug_fatalerror': LLOp(),
}
# __________ operations on PyObjects __________
More information about the Pypy-commit
mailing list