[pypy-svn] r51174 - in pypy/branch/jit-refactoring/pypy/jit: rainbow rainbow/test timeshifter
cfbolz at codespeak.net
cfbolz at codespeak.net
Fri Feb 1 13:47:42 CET 2008
Author: cfbolz
Date: Fri Feb 1 13:47:40 2008
New Revision: 51174
Added:
pypy/branch/jit-refactoring/pypy/jit/rainbow/test/test_interpreter.py (contents, props changed)
Modified:
pypy/branch/jit-refactoring/pypy/jit/rainbow/bytecode.py
pypy/branch/jit-refactoring/pypy/jit/timeshifter/rtimeshift.py
Log:
the first test where the rainbow interpreter actually runs passes. required a
very messy test runner and some whacking.
Modified: pypy/branch/jit-refactoring/pypy/jit/rainbow/bytecode.py
==============================================================================
--- pypy/branch/jit-refactoring/pypy/jit/rainbow/bytecode.py (original)
+++ pypy/branch/jit-refactoring/pypy/jit/rainbow/bytecode.py Fri Feb 1 13:47:40 2008
@@ -1,3 +1,4 @@
+from pypy.rlib.rarithmetic import intmask
from pypy.objspace.flow import model as flowmodel
from pypy.rpython.lltypesystem import lltype
from pypy.jit.hintannotator.model import originalconcretetype
@@ -24,15 +25,40 @@
def _freeze_(self):
return True
+SIGN_EXTEND2 = 1 << 15
+
+STOP = object()
+
class JitInterpreter(object):
def __init__(self):
self.opcode_implementations = []
self.opcode_descs = []
self.opname_to_index = {}
self.jitstate = None
+ self.queue = None
self.bytecode = None
+ self.pc = -1
self._add_implemented_opcodes()
+ def run(self, jitstate, bytecode, greenargs, redargs):
+ self.jitstate = jitstate
+ self.queue = rtimeshift.ensure_queue(jitstate,
+ rtimeshift.BaseDispatchQueue)
+ rtimeshift.enter_frame(self.jitstate, self.queue)
+ self.frame = self.jitstate.frame
+ self.frame.pc = 0
+ self.frame.bytecode = bytecode
+ self.frame.local_boxes = redargs
+ self.frame.local_green = greenargs
+ self.bytecode_loop()
+
+ def bytecode_loop(self):
+ while 1:
+ bytecode = self.load_2byte()
+ result = self.opcode_implementations[bytecode](self)
+ if result is STOP:
+ return
+
# construction-time interface
def _add_implemented_opcodes(self):
@@ -44,7 +70,6 @@
self.opcode_implementations.append(getattr(self, name).im_func)
self.opcode_descs.append(None)
-
def find_opcode(self, name):
return self.opname_to_index.get(name, -1)
@@ -54,7 +79,9 @@
def implementation(self):
args = ()
for i in numargs:
- args.append(self.get_greenarg())
+ genconst = self.get_greenarg()
+ arg = self.jitstate.curbuilder.revealconst(opdesc.ARGS[i])
+ args += (arg, )
result = opdesc.llop(*args)
self.green_result(result)
elif color == "red":
@@ -65,12 +92,9 @@
else:
XXX
def implementation(self):
- XXX
- # the following is nonsense: the green arguments are
- # GenConsts, so there are revealconsts missing
- args = (self.jitstate, )
+ args = (opdesc, self.jitstate, )
for i in numargs:
- args.append(self.get_redarg())
+ args += (self.get_redarg(), )
result = impl(*args)
self.red_result(result)
else:
@@ -83,12 +107,46 @@
return index
- # operation implemetations
+ # operation helper functions
+
+ def load_2byte(self):
+ pc = self.frame.pc
+ result = ((ord(self.frame.bytecode.code[pc]) << 8) |
+ ord(self.frame.bytecode.code[pc + 1]))
+ self.frame.pc = pc + 2
+ return intmask((result ^ SIGN_EXTEND2) - SIGN_EXTEND2)
+
+ def load_4byte(self):
+ pc = self.frame.pc
+ result = ((ord(self.frame.bytecode.code[pc + 0]) << 24) |
+ (ord(self.frame.bytecode.code[pc + 1]) << 16) |
+ (ord(self.frame.bytecode.code[pc + 2]) << 8) |
+ (ord(self.frame.bytecode.code[pc + 3]) << 0))
+ self.frame.pc = pc + 4
+ return intmask(result)
+
+ def get_greenarg(self):
+ i = self.load_2byte()
+ if i < 0:
+ return self.frame.bytecode.constants[~i]
+ return self.frame.local_green[i]
+
+ def get_redarg(self):
+ return self.frame.local_boxes[self.load_2byte()]
+
+ def red_result(self, box):
+ self.frame.local_boxes.append(box)
+
+ def green_result(self, gv):
+ self.frame.local_green.append(gv)
+
+ # operation implementations
def opimpl_make_redbox(self):
XXX
def opimpl_goto(self):
- XXX
+ target = self.load_4byte()
+ self.frame.pc = target
def opimpl_green_goto_iftrue(self):
XXX
@@ -97,20 +155,35 @@
XXX
def opimpl_red_return(self):
- XXX
+ rtimeshift.save_return(self.jitstate)
+ # XXX for now
+ newstate = rtimeshift.leave_graph_red(self.queue, is_portal=True)
+ self.jitstate = newstate
+ return STOP
def opimpl_green_return(self):
XXX
+ return STOP # XXX wrong, of course
def opimpl_make_new_redvars(self):
# an opcode with a variable number of args
# num_args arg_old_1 arg_new_1 ...
- XXX
+ num = self.load_2byte()
+ newlocalboxes = []
+ for i in range(num):
+ newlocalboxes.append(self.get_redarg())
+ self.frame.local_boxes = newlocalboxes
def opimpl_make_new_greenvars(self):
# an opcode with a variable number of args
# num_args arg_old_1 arg_new_1 ...
- XXX
+ num = self.load_2byte()
+ newgreens = []
+ for i in range(num):
+ newgreens.append(self.get_greenarg())
+ self.frame.local_green = newgreens
+
+
class BytecodeWriter(object):
@@ -268,7 +341,6 @@
return color
def register_redvar(self, arg):
- print "register_redvar", arg
assert arg not in self.redvar_positions
self.redvar_positions[arg] = result = self.free_red[self.current_block]
self.free_red[self.current_block] += 1
@@ -288,7 +360,7 @@
def green_position(self, arg):
if isinstance(arg, flowmodel.Variable):
return self.greenvar_positions[arg]
- return -self.const_position(arg) - 1
+ return ~self.const_position(arg)
def const_position(self, const):
if const in self.const_positions:
@@ -374,15 +446,15 @@
-# XXX too lazy to fix the interface of make_opdesc
+# XXX too lazy to fix the interface of make_opdesc, ExceptionDesc
class PseudoHOP(object):
def __init__(self, op, args_s, s_result, RGenOp):
self.spaceop = op
self.args_s = args_s
self.s_result = s_result
- self.rtyper = PseudoHRTyper(RGenOp)
+ self.rtyper = PseudoHRTyper(RGenOp=RGenOp)
class PseudoHRTyper(object):
- def __init__(self, RGenOp):
- self.RGenOp = RGenOp
+ def __init__(self, **args):
+ self.__dict__.update(**args)
Added: pypy/branch/jit-refactoring/pypy/jit/rainbow/test/test_interpreter.py
==============================================================================
--- (empty file)
+++ pypy/branch/jit-refactoring/pypy/jit/rainbow/test/test_interpreter.py Fri Feb 1 13:47:40 2008
@@ -0,0 +1,140 @@
+from pypy.translator.translator import TranslationContext, graphof
+from pypy.jit.hintannotator.annotator import HintAnnotator
+from pypy.jit.hintannotator.policy import StopAtXPolicy, HintAnnotatorPolicy
+from pypy.jit.hintannotator.model import SomeLLAbstractConstant, OriginFlags
+from pypy.jit.hintannotator.model import originalconcretetype
+from pypy.jit.rainbow.bytecode import BytecodeWriter, label, tlabel, assemble
+from pypy.jit.codegen.llgraph.rgenop import RGenOp
+from pypy.jit.rainbow.test.test_serializegraph import AbstractSerializationTest
+from pypy.jit.rainbow import bytecode
+from pypy.jit.timeshifter import rtimeshift, exception, rvalue
+from pypy.rpython.lltypesystem import lltype, rstr
+from pypy.rpython.llinterp import LLInterpreter
+from pypy.annotation import model as annmodel
+from pypy import conftest
+
+def getargtypes(annotator, values):
+ return [annotation(annotator, x) for x in values]
+
+def annotation(a, x):
+ T = lltype.typeOf(x)
+ if T == lltype.Ptr(rstr.STR):
+ t = str
+ else:
+ t = annmodel.lltype_to_annotation(T)
+ return a.typeannotation(t)
+
+P_OOPSPEC_NOVIRTUAL = HintAnnotatorPolicy(oopspec=True,
+ novirtualcontainer=True,
+ entrypoint_returns_red=False)
+
+class AbstractInterpretationTest(object):
+
+ def serialize(self, func, values, backendoptimize=False):
+ # build the normal ll graphs for ll_function
+ t = TranslationContext()
+ a = t.buildannotator()
+ argtypes = getargtypes(a, values)
+ a.build_types(func, argtypes)
+ rtyper = t.buildrtyper(type_system = self.type_system)
+ rtyper.specialize()
+ self.rtyper = rtyper
+ 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=P_OOPSPEC_NOVIRTUAL)
+ hs = hannotator.build_types(graph1, [SomeLLAbstractConstant(v.concretetype,
+ {OriginFlags(): True})
+ for v in graph1.getargs()])
+ hannotator.simplify()
+ t = hannotator.translator
+ self.hannotator = hannotator
+ if conftest.option.view:
+ t.view()
+ graph2 = graphof(t, func)
+ self.graph = graph2
+ writer = BytecodeWriter(t, hannotator, RGenOp)
+ jitcode = writer.make_bytecode(graph2)
+ argcolors = []
+ for i, ll_val in enumerate(values):
+ color = writer.varcolor(graph2.startblock.inputargs[i])
+ argcolors.append(color)
+ return writer, jitcode, argcolors
+
+ def interpret(self, ll_function, values, opt_consts=[], *args, **kwds):
+ # XXX clean this mess up
+ writer, jitcode, argcolors = self.serialize(ll_function, values)
+ hrtyper = bytecode.PseudoHRTyper(RGenOp=writer.RGenOp,
+ annotator=writer.translator.annotator,
+ rtyper=writer.translator.annotator.base_translator.rtyper)
+ edesc = exception.ExceptionDesc(hrtyper, False)
+ rgenop = writer.RGenOp()
+ # make residual functype
+ FUNC = lltype.FuncType([lltype.Signed], lltype.Signed)
+ ha = self.hannotator
+ RESTYPE = originalconcretetype(self.hannotator.binding(self.graph.getreturnvar()))
+ ARGS = []
+ for var in self.graph.getargs():
+ # XXX ignoring virtualizables for now
+ ARGS.append(originalconcretetype(self.hannotator.binding(var)))
+ FUNC = lltype.FuncType(ARGS, RESTYPE)
+ sigtoken = rgenop.sigToken(FUNC)
+ builder, gv_generated, inputargs_gv = rgenop.newgraph(sigtoken, "generated")
+ print builder, builder.rgenop, rgenop
+ builder.start_writing()
+ jitstate = rtimeshift.JITState(builder, None,
+ edesc.null_exc_type_box,
+ edesc.null_exc_value_box)
+ def ll_finish_jitstate(jitstate, exceptiondesc, graphsigtoken):
+ returnbox = rtimeshift.getreturnbox(jitstate)
+ gv_ret = returnbox.getgenvar(jitstate)
+ builder = jitstate.curbuilder
+ for virtualizable_box in jitstate.virtualizables:
+ assert isinstance(virtualizable_box, rvalue.PtrRedBox)
+ content = virtualizable_box.content
+ assert isinstance(content, rcontainer.VirtualizableStruct)
+ content.store_back(jitstate)
+ exceptiondesc.store_global_excdata(jitstate)
+ jitstate.curbuilder.finish_and_return(graphsigtoken, gv_ret)
+ # build arguments
+ greenargs = []
+ redargs = []
+ residualargs = []
+ i = 0
+ for color, ll_val in zip(argcolors, values):
+ if color == "green":
+ greenargs.append(writer.RGenOp.constPrebuiltGlobal(const.value))
+ else:
+ TYPE = lltype.typeOf(ll_val)
+ kind = rgenop.kindToken(TYPE)
+ boxcls = rvalue.ll_redboxcls(TYPE)
+ redargs.append(boxcls(kind, inputargs_gv[i]))
+ residualargs.append(ll_val)
+ i += 1
+ writer.interpreter.run(jitstate, jitcode, greenargs, redargs)
+ ll_finish_jitstate(writer.interpreter.jitstate, edesc, sigtoken)
+ builder.end()
+ generated = gv_generated.revealconst(lltype.Ptr(FUNC))
+ graph = generated._obj.graph
+ if conftest.option.view:
+ graph.show()
+ llinterp = LLInterpreter(self.rtyper)
+ res = llinterp.eval_graph(graph, residualargs)
+ return res
+
+ def Xtest_return_green(self):
+ def f():
+ return 1
+ self.interpret(f, [])
+
+ def test_very_simple(self):
+ def f(x, y):
+ return x + y
+ res = self.interpret(f, [1, 2])
+ assert res == 3
+
+class TestLLType(AbstractInterpretationTest):
+ type_system = "lltype"
Modified: pypy/branch/jit-refactoring/pypy/jit/timeshifter/rtimeshift.py
==============================================================================
--- pypy/branch/jit-refactoring/pypy/jit/timeshifter/rtimeshift.py (original)
+++ pypy/branch/jit-refactoring/pypy/jit/timeshifter/rtimeshift.py Fri Feb 1 13:47:40 2008
@@ -78,7 +78,7 @@
def ll_gen1(opdesc, jitstate, argbox):
ARG0 = opdesc.ARG0
RESULT = opdesc.RESULT
- opname = opdesc.name
+ opname = opdesc.opname
if opdesc.tryfold and argbox.is_constant():
arg = rvalue.ll_getvalue(argbox, ARG0)
if not opdesc.canraise:
@@ -106,7 +106,7 @@
ARG0 = opdesc.ARG0
ARG1 = opdesc.ARG1
RESULT = opdesc.RESULT
- opname = opdesc.name
+ opname = opdesc.opname
if opdesc.tryfold and argbox0.is_constant() and argbox1.is_constant():
# const propagate
arg0 = rvalue.ll_getvalue(argbox0, ARG0)
@@ -991,6 +991,7 @@
self.backframe = backframe
self.dispatchqueue = dispatchqueue
#self.local_boxes = ... set by callers
+ #self.local_green = ... set by callers
def enter_block(self, incoming, memo):
for box in self.local_boxes:
More information about the Pypy-commit
mailing list