[pypy-svn] r32239 - in pypy/dist/pypy: jit/hintannotator jit/hintannotator/test jit/timeshifter jit/timeshifter/test rpython
arigo at codespeak.net
arigo at codespeak.net
Tue Sep 12 21:03:07 CEST 2006
Author: arigo
Date: Tue Sep 12 21:03:04 2006
New Revision: 32239
Added:
pypy/dist/pypy/jit/timeshifter/test/test_tlc.py
- copied, changed from r32217, pypy/dist/pypy/jit/timeshifter/test/test_tl.py
Modified:
pypy/dist/pypy/jit/hintannotator/bookkeeper.py
pypy/dist/pypy/jit/hintannotator/test/test_annotator.py
pypy/dist/pypy/jit/hintannotator/test/test_toy.py
pypy/dist/pypy/jit/timeshifter/rtyper.py
pypy/dist/pypy/jit/timeshifter/test/test_timeshift.py
pypy/dist/pypy/jit/timeshifter/timeshift.py
pypy/dist/pypy/rpython/rtyper.py
Log:
(pedronis, arigo)
started timeshifting support for indirect calls, still in progress, we bumped into normalisation problems.
Modified: pypy/dist/pypy/jit/hintannotator/bookkeeper.py
==============================================================================
--- pypy/dist/pypy/jit/hintannotator/bookkeeper.py (original)
+++ pypy/dist/pypy/jit/hintannotator/bookkeeper.py Tue Sep 12 21:03:04 2006
@@ -137,30 +137,36 @@
def warning(self, msg):
return self.annotator.warning(msg)
- def get_graph_for_call(self, graph, fixed, args_hs):
- # this can modify args_hs in-place!
- from pypy.jit.hintannotator.model import SomeLLAbstractConstant
- desc = self.getdesc(graph)
- key = None
- alt_name = None
+ def specialization_key(self, fixed, args_hs):
if fixed:
- key = 'fixed'
- alt_name = graph.name + '_HFixed'
+ return 'fixed'
else:
key = []
specialize = False
for i, arg_hs in enumerate(args_hs):
- if isinstance(arg_hs, SomeLLAbstractConstant) and arg_hs.eager_concrete:
+ if (isinstance(arg_hs, hintmodel.SomeLLAbstractConstant)
+ and arg_hs.eager_concrete):
key.append('E')
specialize = True
else:
key.append('x')
if specialize:
- key = ''.join(key)
- alt_name = graph.name + '_H'+key
+ return ''.join(key)
else:
- key = None
+ return None
+
+ def get_graph_by_key(self, graph, specialization_key):
+ desc = self.getdesc(graph)
+ return desc._cache[specialization_key]
+ def get_graph_for_call(self, graph, fixed, args_hs):
+ # this can modify args_hs in-place!
+ key = self.specialization_key(fixed, args_hs)
+ if key is None:
+ alt_name = None
+ else:
+ alt_name = graph.name + '_H'+key
+ desc = self.getdesc(graph)
graph = desc.specialize(args_hs, key=key, alt_name=alt_name)
return graph
Modified: pypy/dist/pypy/jit/hintannotator/test/test_annotator.py
==============================================================================
--- pypy/dist/pypy/jit/hintannotator/test/test_annotator.py (original)
+++ pypy/dist/pypy/jit/hintannotator/test/test_annotator.py Tue Sep 12 21:03:04 2006
@@ -18,7 +18,8 @@
P_OOPSPEC_NOVIRTUAL.oopspec = True
P_OOPSPEC_NOVIRTUAL.novirtualcontainer = True
-def hannotate(func, argtypes, policy=None, annotator=False, inline=None):
+def hannotate(func, argtypes, policy=None, annotator=False, inline=None,
+ backendoptimize=False):
# build the normal ll graphs for ll_function
t = TranslationContext()
a = t.buildannotator()
@@ -27,6 +28,9 @@
rtyper.specialize()
if inline:
auto_inlining(t, inline)
+ if backendoptimize:
+ from pypy.translator.backendopt.all import backend_optimizations
+ backend_optimizations(t)
graph1 = graphof(t, func)
# build hint annotator types
hannotator = HintAnnotator(base_translator=t, policy=policy)
Modified: pypy/dist/pypy/jit/hintannotator/test/test_toy.py
==============================================================================
--- pypy/dist/pypy/jit/hintannotator/test/test_toy.py (original)
+++ pypy/dist/pypy/jit/hintannotator/test/test_toy.py Tue Sep 12 21:03:04 2006
@@ -17,4 +17,4 @@
def test_hannotate_tlc_novirtual():
from pypy.jit.tl import tlc
hannotate(tlc.interp_without_call, [str, int, int],
- policy=P_OOPSPEC_NOVIRTUAL)
+ policy=P_OOPSPEC_NOVIRTUAL, backendoptimize=True)
Modified: pypy/dist/pypy/jit/timeshifter/rtyper.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/rtyper.py (original)
+++ pypy/dist/pypy/jit/timeshifter/rtyper.py Tue Sep 12 21:03:04 2006
@@ -333,6 +333,8 @@
def guess_call_kind(self, spaceop):
+ if spaceop.opname == 'indirect_call':
+ return 'red' # for now
assert spaceop.opname == 'direct_call'
c_func = spaceop.args[0]
fnobj = c_func.value._obj
@@ -351,6 +353,34 @@
meth = getattr(self, 'handle_%s_call' % (kind,))
return meth(hop)
+ def translate_op_indirect_call(self, hop):
+ bk = self.annotator.bookkeeper
+ ts = self.timeshifter
+ v_jitstate = hop.llops.getjitstate()
+ v_funcbox = hop.args_v[0]
+ graph_list = hop.args_v[-1].value
+ hop.r_s_pop(0)
+ hop.r_s_pop()
+ args_hs = hop.args_s[:]
+ # fixed is always false here
+ specialization_key = bk.specialization_key(False, args_hs)
+ FUNC = ts.originalconcretetype(v_funcbox)
+
+ mapper, TS_FUNC, args_r, tsgraphs = ts.get_timeshift_mapper(
+ FUNC, specialization_key, graph_list)
+ args_v = hop.inputargs(*args_r)
+
+ v_tsfunc = hop.llops.genmixlevelhelpercall(mapper,
+ [ts.s_RedBox],
+ [v_funcbox],
+ annmodel.SomePtr(TS_FUNC))
+ args_v[:0] = [v_tsfunc, v_jitstate]
+ RESULT = v_tsfunc.concretetype.TO.RESULT
+ args_v.append(hop.inputconst(lltype.Void, tsgraphs))
+ v_newjitstate = hop.genop('indirect_call', args_v, RESULT)
+ hop.llops.setjitstate(v_newjitstate)
+
+
def translate_op_save_locals(self, hop):
ts = self.timeshifter
v_jitstate = hop.llops.getjitstate()
@@ -441,18 +471,12 @@
hop.r_s_popfirstarg()
args_hs = hop.args_s[:]
# fixed is always false here
- graph = bk.get_graph_for_call(fnobj.graph, False, args_hs)
- args_r = [self.getrepr(hs) for hs in args_hs]
+ specialization_key = bk.specialization_key(False, args_hs)
+ fnptr, args_r = ts.get_timeshifted_fnptr(fnobj.graph,
+ specialization_key)
args_v = hop.inputargs(*args_r)
- ARGS = [ts.r_JITState.lowleveltype]
- ARGS += [r.lowleveltype for r in args_r]
- RESULT = ts.r_JITState.lowleveltype
- fnptr = lltype.functionptr(lltype.FuncType(ARGS, RESULT),
- graph.name,
- graph=graph,
- _callable = graph.func)
- self.timeshifter.schedule_graph(graph)
args_v[:0] = [hop.llops.genconst(fnptr), v_jitstate]
+ RESULT = lltype.typeOf(fnptr).TO.RESULT
v_newjitstate = hop.genop('direct_call', args_v, RESULT)
hop.llops.setjitstate(v_newjitstate)
@@ -491,7 +515,10 @@
# build the 'direct_call' operation
rtyper = self.timeshifter.rtyper
- RESULT = rtyper.getrepr(s_result).lowleveltype
+ try:
+ RESULT = annmodel.annotation_to_lltype(s_result)
+ except ValueError:
+ RESULT = rtyper.getrepr(s_result).lowleveltype
return self.genop('direct_call', [c]+args_v,
resulttype = RESULT)
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 Sep 12 21:03:04 2006
@@ -33,7 +33,7 @@
t = annmodel.lltype_to_annotation(T)
return a.typeannotation(t)
-def hannotate(func, values, policy=None, inline=None):
+def hannotate(func, values, policy=None, inline=None, backendoptimize=False):
# build the normal ll graphs for ll_function
t = TranslationContext()
a = t.buildannotator()
@@ -43,6 +43,9 @@
rtyper.specialize()
if inline:
auto_inlining(t, inline)
+ if backendoptimize:
+ from pypy.translator.backendopt.all import backend_optimizations
+ backend_optimizations(t)
graph1 = graphof(t, func)
# build hint annotator types
hannotator = HintAnnotator(base_translator=t, policy=policy)
@@ -66,7 +69,8 @@
del cls._cache_order
def timeshift_cached(self, ll_function, values, inline=None, policy=None,
- check_raises='ignored anyway'):
+ check_raises='ignored anyway',
+ backendoptimize=False):
# decode the 'values' if they are specified as strings
if hasattr(ll_function, 'convert_arguments'):
assert len(ll_function.convert_arguments) == len(values)
@@ -86,7 +90,8 @@
if len(self._cache_order) >= 3:
del self._cache[self._cache_order.pop(0)]
hs, ha, rtyper = hannotate(ll_function, values,
- inline=inline, policy=policy)
+ inline=inline, policy=policy,
+ backendoptimize=backendoptimize)
# make the timeshifted graphs
htshift = HintTimeshift(ha, rtyper, self.RGenOp)
Modified: pypy/dist/pypy/jit/timeshifter/timeshift.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/timeshift.py (original)
+++ pypy/dist/pypy/jit/timeshifter/timeshift.py Tue Sep 12 21:03:04 2006
@@ -24,8 +24,9 @@
self.rtyper = rtyper
self.RGenOp = RGenOp
self.hrtyper = HintRTyper(hannotator, self)
- self.latestexitindex = -1
self.annhelper = annlowlevel.MixLevelHelperAnnotator(rtyper)
+ self.timeshift_mapping = {}
+ self.sigs = {}
self.s_CodeGenerator, self.r_CodeGenerator = self.s_r_instanceof(
cgmodel.CodeGenerator)
@@ -124,9 +125,84 @@
# Return a SomeInstance / InstanceRepr pair correspnding to the specified class.
return self.annhelper.s_r_instanceof(cls, can_be_None=can_be_None)
+ def get_sig_hs(self, tsgraph):
+ # the signature annotations are cached here because
+ # the graph is going to be modified
+ try:
+ return self.sigs[tsgraph]
+ except KeyError:
+ ha = self.hannotator
+ sig_hs = ([ha.binding(v) for v in tsgraph.getargs()],
+ ha.binding(tsgraph.getreturnvar()))
+ self.sigs[tsgraph] = sig_hs
+ return sig_hs
+
+ def get_timeshifted_fnptr(self, graph, specialization_key):
+ bk = self.hannotator.bookkeeper
+ tsgraph = bk.get_graph_by_key(graph, specialization_key)
+ args_hs, hs_res = self.get_sig_hs(tsgraph)
+ args_r = [self.hrtyper.getrepr(hs_arg) for hs_arg in args_hs]
+ ARGS = [self.r_JITState.lowleveltype]
+ ARGS += [r.lowleveltype for r in args_r]
+ RESULT = self.r_JITState.lowleveltype
+ fnptr = lltype.functionptr(lltype.FuncType(ARGS, RESULT),
+ tsgraph.name,
+ graph=tsgraph,
+ _callable = graph.func)
+ self.schedule_graph(tsgraph)
+ return fnptr, args_r
+
def error_value(self, TYPE):
return exceptiontransform.error_value(TYPE)
+ def get_timeshift_mapper(self, FUNC, specialization_key, graphs):
+ key = FUNC, specialization_key
+ try:
+ timeshift_mapper, values, keys = self.timeshift_mapping[key]
+ except KeyError:
+ values = []
+ keys = []
+ fnptrmap = {}
+
+ def getter(fnptrmap, fnptr):
+ # indirection needed to defeat the flow object space
+ return fnptrmap[fnptr]
+
+ def fill_dict(fnptrmap, values, keys):
+ for i in range(len(values)):
+ fnptrmap[values[i]] = keys[i]
+
+ def timeshift_mapper(fnptrbox):
+ fnptr = rvalue.ll_getvalue(fnptrbox, FUNC)
+ try:
+ return getter(fnptrmap, fnptr)
+ except KeyError:
+ fill_dict(fnptrmap, values, keys)
+ return getter(fnptrmap, fnptr) # try again
+
+ self.timeshift_mapping[key] = timeshift_mapper, values, keys
+
+ bk = self.hannotator.bookkeeper
+ common_args_r = None
+ COMMON_TS_FUNC = None
+ tsgraphs = []
+ for graph in graphs:
+ fnptr = self.rtyper.getcallable(graph)
+ ts_fnptr, args_r = self.get_timeshifted_fnptr(graph,
+ specialization_key)
+ tsgraphs.append(ts_fnptr._obj.graph)
+ TS_FUNC = lltype.typeOf(ts_fnptr)
+ if common_args_r is None:
+ common_args_r = args_r
+ COMMON_TS_FUNC = TS_FUNC
+ else:
+ # XXX for now
+ assert COMMON_TS_FUNC == TS_FUNC
+ assert common_args_r == args_r
+ keys.append(fnptr)
+ values.append(ts_fnptr)
+ return timeshift_mapper, COMMON_TS_FUNC, common_args_r, tsgraphs
+
# creates and numbers reentry_block for block reached by link
# argument:
#
@@ -199,21 +275,29 @@
def timeshift_graph(self, graph):
#print 'timeshift_graph START', graph
+ assert graph.startblock in self.hannotator.annotated
self.graph = graph
self.dispatch_to = []
self.statecaches = []
self.return_cache = None
- entering_links = flowmodel.mkentrymap(graph)
+ self.latestexitindex = -1
+
+ # cache the annotation signature before changing the graph
+ args_hs, hs_res = self.get_sig_hs(graph)
+ assert (originalconcretetype(hs_res) is lltype.Void
+ or not hs_res.is_green()) # XXX not supported yet
originalblocks = list(graph.iterblocks())
timeshifted_blocks = []
for block in originalblocks:
- self.timeshift_block(timeshifted_blocks, entering_links, block)
+ self.timeshift_block(timeshifted_blocks, block)
originalblocks = timeshifted_blocks
+ entering_links = flowmodel.mkentrymap(graph)
inputlinkcounters = {}
for block in originalblocks:
inputlinkcounters[block] = len(entering_links[block])
+ # XXX try to not use entering_links in the sequel
returnblock = graph.returnblock
self.r_returnvalue = self.hrtyper.bindingrepr(returnblock.inputargs[0])
@@ -296,8 +380,9 @@
block.isstartblock = False
newblock.isstartblock = True
self.graph.startblock = newblock
- else:
+ if block_entering_links:
for link in block_entering_links:
+ assert link.target is block
link.settarget(newblock)
if closeblock:
@@ -629,14 +714,14 @@
dispatchblock.closeblock(*exitlinks)
- def timeshift_block(self, timeshifted_blocks, entering_links, block):
+ def timeshift_block(self, timeshifted_blocks, block):
hrtyper = self.hrtyper
blocks = [block]
i = 0
# XXX in-progress, split block at direct_calls for call support
while i < len(block.operations):
op = block.operations[i]
- if (op.opname == 'direct_call'
+ if (op.opname in ('direct_call', 'indirect_call')
and hrtyper.guess_call_kind(op) == 'red'):
link = support.split_block_with_keepalive(block, i+1,
@@ -682,7 +767,6 @@
link.args = [replacement.get(var, var) for var in link.args]
block = link.target
- entering_links[block] = [link]
blocks.append(block)
self.hannotator.annotated[block] = self.graph
# for now the call doesn't return its redbox result, but only
Modified: pypy/dist/pypy/rpython/rtyper.py
==============================================================================
--- pypy/dist/pypy/rpython/rtyper.py (original)
+++ pypy/dist/pypy/rpython/rtyper.py Tue Sep 12 21:03:04 2006
@@ -721,11 +721,15 @@
def gendirectcall(self, ll_function, *args_v):
return self.llops.gendirectcall(ll_function, *args_v)
+ def r_s_pop(self, index=-1):
+ "Return and discard the argument with index position."
+ self.nb_args -= 1
+ self.args_v.pop(index)
+ return self.args_r.pop(index), self.args_s.pop(index)
+
def r_s_popfirstarg(self):
"Return and discard the first argument."
- self.nb_args -= 1
- self.args_v.pop(0)
- return self.args_r.pop(0), self.args_s.pop(0)
+ return self.r_s_pop(0)
def v_s_insertfirstarg(self, v_newfirstarg, s_newfirstarg):
r_newfirstarg = self.rtyper.getrepr(s_newfirstarg)
More information about the Pypy-commit
mailing list