[pypy-svn] r31614 - in pypy/dist/pypy: annotation jit/codegen/llgraph jit/timeshifter jit/timeshifter/test objspace/flow rpython
arigo at codespeak.net
arigo at codespeak.net
Thu Aug 24 18:19:58 CEST 2006
Author: arigo
Date: Thu Aug 24 18:19:50 2006
New Revision: 31614
Modified:
pypy/dist/pypy/annotation/annrpython.py
pypy/dist/pypy/annotation/specialize.py
pypy/dist/pypy/annotation/unaryop.py
pypy/dist/pypy/jit/codegen/llgraph/rgenop.py
pypy/dist/pypy/jit/timeshifter/rtimeshift.py
pypy/dist/pypy/jit/timeshifter/rvalue.py
pypy/dist/pypy/jit/timeshifter/test/test_timeshift.py
pypy/dist/pypy/jit/timeshifter/timeshift.py
pypy/dist/pypy/objspace/flow/model.py
pypy/dist/pypy/rpython/annlowlevel.py
pypy/dist/pypy/rpython/rtyper.py
Log:
(pedronis, arigo)
Refactor the timeshifter test runner to be parametrizable on the RGenOp.
Caused a lot of pain and obscure crashes. Added sanity checks and XXXs
a bit everywhere.
Modified: pypy/dist/pypy/annotation/annrpython.py
==============================================================================
--- pypy/dist/pypy/annotation/annrpython.py (original)
+++ pypy/dist/pypy/annotation/annrpython.py Thu Aug 24 18:19:50 2006
@@ -169,15 +169,24 @@
def addpendingblock(self, graph, block, cells, called_from_graph=None):
"""Register an entry point into block with the given input cells."""
- assert not self.frozen
- for a in cells:
- assert isinstance(a, annmodel.SomeObject)
- if block not in self.annotated:
- self.bindinputargs(graph, block, cells, called_from_graph)
+ if graph in self.fixed_graphs:
+ # special case for annotating/rtyping in several phases: calling
+ # a graph that has already been rtyped. Safety-check the new
+ # annotations that are passed in, and don't annotate the old
+ # graph -- it's already low-level operations!
+ for a, s_newarg in zip(graph.getargs(), cells):
+ s_oldarg = self.binding(a)
+ assert s_oldarg.contains(s_newarg)
else:
- self.mergeinputargs(graph, block, cells, called_from_graph)
- if not self.annotated[block]:
- self.pendingblocks[block] = graph
+ assert not self.frozen
+ for a in cells:
+ assert isinstance(a, annmodel.SomeObject)
+ if block not in self.annotated:
+ self.bindinputargs(graph, block, cells, called_from_graph)
+ else:
+ self.mergeinputargs(graph, block, cells, called_from_graph)
+ if not self.annotated[block]:
+ self.pendingblocks[block] = graph
def complete(self):
"""Process pending blocks until none is left."""
@@ -348,17 +357,8 @@
callpositions[callback] = True
# generalize the function's input arguments
- if graph in self.fixed_graphs:
- # special case for annotating/rtyping in several phases: calling
- # a graph that has already been rtyped. Safety-check the new
- # annotations that are passed in, and don't annotate the old
- # graph -- it's already low-level operations!
- for a, s_newarg in zip(graph.getargs(), inputcells):
- s_oldarg = self.binding(a)
- assert s_oldarg.contains(s_newarg)
- else:
- self.addpendingblock(graph, graph.startblock, inputcells,
- position_key)
+ self.addpendingblock(graph, graph.startblock, inputcells,
+ position_key)
# get the (current) return value
v = graph.getreturnvar()
@@ -456,6 +456,7 @@
def reflowpendingblock(self, graph, block):
assert not self.frozen
+ assert graph not in self.fixed_graphs
self.pendingblocks[block] = graph
assert block in self.annotated
self.annotated[block] = False # must re-flow
Modified: pypy/dist/pypy/annotation/specialize.py
==============================================================================
--- pypy/dist/pypy/annotation/specialize.py (original)
+++ pypy/dist/pypy/annotation/specialize.py Thu Aug 24 18:19:50 2006
@@ -77,6 +77,7 @@
def finish(self):
from pypy.annotation.model import unionof
+ assert self.graph is None, "MemoTable already finished"
# list of which argument positions can take more than one value
example_args, example_value = self.table.iteritems().next()
nbargs = len(example_args)
@@ -236,15 +237,12 @@
def compute_one_result(args):
value = func(*args)
- return MemoTable(funcdesc, args, value)
-
- def finish():
- for memotable in memotables.infos():
- memotable.finish()
+ memotable = MemoTable(funcdesc, args, value)
+ bookkeeper.pending_specializations.append(memotable.finish)
+ return memotable
memotables = UnionFind(compute_one_result)
bookkeeper.all_specializations[funcdesc] = memotables
- bookkeeper.pending_specializations.append(finish)
# merge the MemoTables for the individual argument combinations
firstvalues = possiblevalues.next()
Modified: pypy/dist/pypy/annotation/unaryop.py
==============================================================================
--- pypy/dist/pypy/annotation/unaryop.py (original)
+++ pypy/dist/pypy/annotation/unaryop.py Thu Aug 24 18:19:50 2006
@@ -607,8 +607,11 @@
v_lltype = annotation_to_lltype(s_value)
setattr(example, s_attr.const, v_lltype._defl())
- def simple_call(p, *args_s):
- llargs = [annotation_to_lltype(arg_s)._defl() for arg_s in args_s]
+ def call(p, args):
+ args_s, kwds_s = args.unpack()
+ if kwds_s:
+ raise Exception("keyword arguments to call to a low-level fn ptr")
+ llargs = [annotation_to_lltype(s_arg)._defl() for s_arg in args_s]
v = p.ll_ptrtype._example()(*llargs)
return ll_to_annotation(v)
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 Thu Aug 24 18:19:50 2006
@@ -87,7 +87,11 @@
# not RPython, just for debugging. Specific to llgraph.
def reveal(gv):
- return llimpl.reveal(gv.v)
+ if hasattr(gv, 'v'):
+ v = gv.v
+ else:
+ v = fishllattr(gv, 'v')
+ return llimpl.reveal(v)
reveal = staticmethod(reveal)
# Builds a real flow.model.FunctionGraph. Specific to llgraph.
@@ -99,8 +103,6 @@
return llimpl.buildgraph(b)
buildgraph = staticmethod(buildgraph)
- testgengraph = staticmethod(llimpl.testgengraph)
-
def get_rgenop_for_testing():
return rgenop
get_rgenop_for_testing = staticmethod(get_rgenop_for_testing)
Modified: pypy/dist/pypy/jit/timeshifter/rtimeshift.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/rtimeshift.py (original)
+++ pypy/dist/pypy/jit/timeshifter/rtimeshift.py Thu Aug 24 18:19:50 2006
@@ -366,7 +366,10 @@
def ll_close_builder(builder):
builder.finish_and_return()
-
+
+def ll_gencallableconst(builder, name, startblock, gv_functype):
+ return builder.rgenop.gencallableconst(name, startblock, gv_functype)
+
class JITState(object):
# XXX obscure interface
localredboxes = None
Modified: pypy/dist/pypy/jit/timeshifter/rvalue.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/rvalue.py (original)
+++ pypy/dist/pypy/jit/timeshifter/rvalue.py Thu Aug 24 18:19:50 2006
@@ -67,9 +67,9 @@
return IntRedBox
def redboxbuilder_void(gv_type, gv_value):return None
-def redboxbuilder_int(gv_ptr, gv_value): return IntRedBox(gv_ptr, gv_value)
-def redboxbuilder_dbl(gv_ptr, gv_value): return DoubleRedBox(gv_ptr, gv_value)
-def redboxbuilder_ptr(gv_ptr, gv_value): return PtrRedBox(gv_ptr, gv_value)
+def redboxbuilder_int(gv_type, gv_value): return IntRedBox(gv_type, gv_value)
+def redboxbuilder_dbl(gv_type, gv_value): return DoubleRedBox(gv_type,gv_value)
+def redboxbuilder_ptr(gv_type, gv_value): return PtrRedBox(gv_type, gv_value)
def ll_redboxbuilder(TYPE):
if TYPE is lltype.Void:
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 Thu Aug 24 18:19:50 2006
@@ -4,12 +4,14 @@
from pypy.jit.hintannotator.bookkeeper import HintBookkeeper
from pypy.jit.hintannotator.model import *
from pypy.jit.timeshifter.timeshift import HintTimeshift
-from pypy.jit.timeshifter import rtimeshift, rtyper as hintrtyper
+from pypy.jit.timeshifter import rtimeshift, rvalue, rtyper as hintrtyper
from pypy.jit.llabstractinterp.test.test_llabstractinterp import annotation
from pypy.jit.llabstractinterp.test.test_llabstractinterp import summary
from pypy.rpython.lltypesystem import lltype, llmemory
from pypy.rpython.objectmodel import hint, keepalive_until_here
+from pypy.rpython.unroll import unrolling_iterable
from pypy.rpython.lltypesystem import rstr
+from pypy.rpython.annlowlevel import PseudoHighLevelCallable
from pypy.annotation import model as annmodel
from pypy.rpython.llinterp import LLInterpreter
from pypy.objspace.flow.model import checkgraph
@@ -65,6 +67,8 @@
hs, ha, rtyper = hannotate(ll_function, values,
inline=inline, policy=policy)
htshift = HintTimeshift(ha, rtyper, self.RGenOp)
+ RESTYPE = htshift.originalconcretetype(
+ ha.translator.graphs[0].getreturnvar())
htshift.timeshift()
t = rtyper.annotator.translator
for graph in ha.translator.graphs:
@@ -73,62 +77,101 @@
if conftest.option.view:
from pypy.translator.tool.graphpage import FlowGraphPage
FlowGraphPage(t, ha.translator.graphs).display()
- result = hs, ha, rtyper, htshift
+ result = hs, ha, rtyper, htshift, RESTYPE
self._cache[key] = result, getargtypes(rtyper.annotator, values)
self._cache_order.append(key)
else:
- hs, ha, rtyper, htshift = result
+ hs, ha, rtyper, htshift, RESTYPE = result
assert argtypes == getargtypes(rtyper.annotator, values)
return result
def timeshift(self, ll_function, values, opt_consts=[], inline=None,
policy=None):
- hs, ha, rtyper, htshift = self.timeshift_cached(ll_function, values,
- inline, policy)
- # run the time-shifted graph-producing graphs
+ hs, ha, rtyper, htshift, RESTYPE = self.timeshift_cached(
+ ll_function, values, inline, policy)
+ # build a runner function
+ original_entrypoint_graph = rtyper.annotator.translator.graphs[0]
graph1 = ha.translator.graphs[0]
- llinterp = LLInterpreter(rtyper)
- builder = llinterp.eval_graph(htshift.ll_make_builder_graph, [])
- graph1args = [builder, lltype.nullptr(htshift.r_JITState.lowleveltype.TO)]
- residual_graph_args = []
+ timeshifted_entrypoint_fnptr = rtyper.type_system.getcallable(graph1)
assert len(graph1.getargs()) == 2 + len(values)
- for i, (v, llvalue) in enumerate(zip(graph1.getargs()[2:], values)):
+ graph1varargs = graph1.getargs()[2:]
+
+ argdescription = [] # list of: ("green"/"redconst"/"redvar", value)
+ residual_args = []
+ residual_argtypes = []
+ timeshifted_entrypoint_args_s = []
+
+ for i, (v, llvalue) in enumerate(zip(graph1varargs, values)):
r = htshift.hrtyper.bindingrepr(v)
residual_v = r.residual_values(llvalue)
if len(residual_v) == 0:
# green
- graph1args.append(llvalue)
+ color = "green"
+ s_var = annmodel.ll_to_annotation(llvalue)
+ timeshifted_entrypoint_args_s.append(s_var)
else:
# red
assert residual_v == [llvalue], "XXX for now"
- TYPE = htshift.originalconcretetype(v)
- gv_type = self.RGenOp.constTYPE(TYPE)
- ll_type = htshift.r_ConstOrVar.convert_const(gv_type)
- ll_gvar = llinterp.eval_graph(htshift.ll_geninputarg_graph,
- [builder, ll_type])
- if i in opt_consts: # XXX what should happen here interface wise is unclear
- gvar = self.RGenOp.constPrebuiltGlobal(llvalue)
- ll_gvar = htshift.r_ConstOrVar.convert_const(gvar)
- if isinstance(lltype.typeOf(llvalue), lltype.Ptr):
- ll_box_graph = htshift.ll_addr_box_graph
- elif isinstance(llvalue, float):
- ll_box_graph = htshift.ll_double_box_graph
+ if i in opt_consts:
+ color = "redconst"
else:
- ll_box_graph = htshift.ll_int_box_graph
- box = llinterp.eval_graph(ll_box_graph, [ll_type, ll_gvar])
- graph1args.append(box)
- residual_graph_args.append(llvalue)
- startblock = llinterp.eval_graph(htshift.ll_end_setup_builder_graph, [builder])
-
- builder = llinterp.eval_graph(graph1, graph1args)
- r = htshift.hrtyper.getrepr(hs)
- llinterp.eval_graph(htshift.ll_close_builder_graph, [builder])
+ color = "redvar"
+ ARGTYPE = htshift.originalconcretetype(v)
+ residual_argtypes.append(ARGTYPE)
+ residual_args.append(llvalue)
+ timeshifted_entrypoint_args_s.append(htshift.s_RedBox)
+ argdescription.append((color, llvalue))
+
+ argdescription = unrolling_iterable(argdescription)
+ RGenOp = self.RGenOp
+ timeshifted_entrypoint = PseudoHighLevelCallable(
+ timeshifted_entrypoint_fnptr,
+ [htshift.s_ResidualGraphBuilder, htshift.s_JITState]
+ + timeshifted_entrypoint_args_s,
+ htshift.s_ResidualGraphBuilder)
+ FUNCTYPE = lltype.FuncType(residual_argtypes, RESTYPE)
+ gv_functype = RGenOp.constTYPE(FUNCTYPE)
+
+ def ll_runner():
+ rgenop = RGenOp.get_rgenop_for_testing()
+ builder = rtimeshift.make_builder(rgenop)
+ timeshifted_entrypoint_args = ()
+ for color, llvalue in argdescription:
+ if color == "green":
+ timeshifted_entrypoint_args += (llvalue,)
+ else:
+ TYPE = lltype.typeOf(llvalue)
+ gv_type = rgenop.constTYPE(TYPE)
+ boxcls = rvalue.ll_redboxcls(TYPE)
+ if color == "redconst":
+ gv_arg = rgenop.genconst(llvalue)
+ else:
+ gv_arg = rtimeshift.ll_geninputarg(builder, gv_type)
+ box = boxcls(gv_type, gv_arg)
+ timeshifted_entrypoint_args += (box,)
+ startblock = rtimeshift.ll_end_setup_builder(builder)
+ endbuilder = timeshifted_entrypoint(builder, None,
+ *timeshifted_entrypoint_args)
+ endbuilder.finish_and_return()
+ gv_generated = rgenop.gencallableconst("generated", startblock,
+ gv_functype)
+ return gv_generated
+
+ annhelper = htshift.annhelper
+ runner_graph = annhelper.getgraph(ll_runner, [], htshift.s_ConstOrVar)
+ annhelper.finish()
+
+ # run the runner
+ llinterp = LLInterpreter(rtyper)
+ ll_gv_generated = llinterp.eval_graph(runner_graph, [])
- # now try to run the blocks produced by the builder
- residual_graph = self.RGenOp.buildgraph(startblock)
+ # now try to run the residual graph generated by the builder
+ c_generatedfn = RGenOp.reveal(ll_gv_generated)
+ residual_graph = c_generatedfn.value._obj.graph
+ if conftest.option.view:
+ residual_graph.show()
insns = summary(residual_graph)
- res = self.RGenOp.testgengraph(residual_graph, residual_graph_args,
- viewbefore = conftest.option.view)
+ res = llinterp.eval_graph(residual_graph, residual_args)
return insns, res
Modified: pypy/dist/pypy/jit/timeshifter/timeshift.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/timeshift.py (original)
+++ pypy/dist/pypy/jit/timeshifter/timeshift.py Thu Aug 24 18:19:50 2006
@@ -55,6 +55,7 @@
rgenop = RGenOp.get_rgenop_for_testing()
return rtimeshift.make_builder(rgenop)
+ # XXX find a different way to enforce the interface types
self.ll_make_builder_graph = self.annhelper.getgraph(
ll_make_builder,
[], self.s_ResidualGraphBuilder)
@@ -88,14 +89,15 @@
rtimeshift.ll_close_builder,
[self.s_ResidualGraphBuilder],
annmodel.s_None)
+ self.annhelper.getgraph(
+ rtimeshift.ll_gencallableconst,
+ [self.s_ResidualGraphBuilder, annmodel.SomeString(),
+ self.s_Block, self.s_ConstOrVar],
+ self.s_ConstOrVar)
def s_r_instanceof(self, cls, can_be_None=True):
# Return a SomeInstance / InstanceRepr pair correspnding to the specified class.
- classdesc = self.rtyper.annotator.bookkeeper.getdesc(cls)
- classdef = classdesc.getuniqueclassdef()
- s_instance = annmodel.SomeInstance(classdef, can_be_None)
- r_instance = self.annhelper.getdelayedrepr(s_instance)
- return s_instance, r_instance
+ return self.annhelper.s_r_instanceof(cls, can_be_None=can_be_None)
# creates and numbers reentry_block for block reached by link
# argument:
Modified: pypy/dist/pypy/objspace/flow/model.py
==============================================================================
--- pypy/dist/pypy/objspace/flow/model.py (original)
+++ pypy/dist/pypy/objspace/flow/model.py Thu Aug 24 18:19:50 2006
@@ -268,6 +268,13 @@
class Variable(object):
__slots__ = ["_name", "_nr", "concretetype"]
+## def getter(x): return x._ct
+## def setter(x, ct):
+## if repr(ct) == '<* PyObject>':
+## import pdb; pdb.set_trace()
+## x._ct = ct
+## concretetype = property(getter, setter)
+
dummyname = 'v'
namesdict = {dummyname : (dummyname, 0)}
Modified: pypy/dist/pypy/rpython/annlowlevel.py
==============================================================================
--- pypy/dist/pypy/rpython/annlowlevel.py (original)
+++ pypy/dist/pypy/rpython/annlowlevel.py Thu Aug 24 18:19:50 2006
@@ -285,6 +285,10 @@
r_res = hop.rtyper.getrepr(self.instance.s_result)
vlist = hop.inputargs(*args_r)
p = self.instance.llfnptr
- c_func = Constant(p, lltype.typeOf(p))
+ TYPE = lltype.typeOf(p)
+ c_func = Constant(p, TYPE)
+ for r_arg, ARGTYPE in zip(args_r, TYPE.TO.ARGS):
+ assert r_arg.lowleveltype == ARGTYPE
+ assert r_res.lowleveltype == TYPE.TO.RESULT
hop.exception_is_here()
return hop.genop('direct_call', [c_func] + vlist, resulttype = r_res)
Modified: pypy/dist/pypy/rpython/rtyper.py
==============================================================================
--- pypy/dist/pypy/rpython/rtyper.py (original)
+++ pypy/dist/pypy/rpython/rtyper.py Thu Aug 24 18:19:50 2006
@@ -67,7 +67,6 @@
self.cache_dummy_values = {}
self.typererrors = []
self.typererror_count = 0
- self.seen_graphs_count = 0
# make the primitive_to_repr constant mapping
self.primitive_to_repr = {}
if self.type_system.offers_exceptiondata:
@@ -233,12 +232,6 @@
if self.typererrors:
self.dump_typererrors(to_log=True)
raise TyperError("there were %d error" % len(self.typererrors))
- # make sure that the return variables of all graphs are concretetype'd
- newgraphs = self.annotator.translator.graphs[self.seen_graphs_count:]
- self.seen_graphs_count += len(newgraphs)
- for graph in newgraphs:
- v = graph.getreturnvar()
- self.setconcretetype(v)
log.event('-=- specialized %d%s blocks -=-' % (blockcount, newtext))
def dump_typererrors(self, num=None, minimize=True, to_log=False):
@@ -311,7 +304,11 @@
def specialize_block(self, block):
graph = self.annotator.annotated[block]
- self.annotator.fixed_graphs[graph] = True
+ if graph not in self.annotator.fixed_graphs:
+ self.annotator.fixed_graphs[graph] = True
+ # make sure that the return variables of all graphs
+ # are concretetype'd
+ self.setconcretetype(graph.getreturnvar())
# give the best possible types to the input args
try:
More information about the Pypy-commit
mailing list