[pypy-svn] r65022 - in pypy/branch/pyjitpl5/pypy: jit/backend/cli jit/backend/cli/test jit/backend/minimal jit/backend/test translator/cli/src

antocuni at codespeak.net antocuni at codespeak.net
Mon May 4 14:40:55 CEST 2009


Author: antocuni
Date: Mon May  4 14:40:54 2009
New Revision: 65022

Added:
   pypy/branch/pyjitpl5/pypy/jit/backend/cli/
   pypy/branch/pyjitpl5/pypy/jit/backend/cli/__init__.py   (contents, props changed)
   pypy/branch/pyjitpl5/pypy/jit/backend/cli/method.py   (contents, props changed)
   pypy/branch/pyjitpl5/pypy/jit/backend/cli/methodfactory.py
      - copied unchanged from r61964, pypy/branch/oo-jit/pypy/jit/codegen/cli/methodfactory.py
   pypy/branch/pyjitpl5/pypy/jit/backend/cli/runner.py   (contents, props changed)
   pypy/branch/pyjitpl5/pypy/jit/backend/cli/test/
   pypy/branch/pyjitpl5/pypy/jit/backend/cli/test/test_runner.py   (contents, props changed)
Modified:
   pypy/branch/pyjitpl5/pypy/jit/backend/minimal/runner.py
   pypy/branch/pyjitpl5/pypy/jit/backend/test/runner.py
   pypy/branch/pyjitpl5/pypy/translator/cli/src/pypylib.cs
Log:
first version of the cli jit backend.  So far, it knows only about int_lshift
and fail operations :-)



Added: pypy/branch/pyjitpl5/pypy/jit/backend/cli/__init__.py
==============================================================================

Added: pypy/branch/pyjitpl5/pypy/jit/backend/cli/method.py
==============================================================================
--- (empty file)
+++ pypy/branch/pyjitpl5/pypy/jit/backend/cli/method.py	Mon May  4 14:40:54 2009
@@ -0,0 +1,163 @@
+from pypy.tool.pairtype import extendabletype
+from pypy.rpython.ootypesystem import ootype
+from pypy.translator.cli import dotnet
+from pypy.translator.cli.dotnet import CLR
+from pypy.jit.metainterp import history
+from pypy.jit.metainterp.history import AbstractValue, Const
+from pypy.jit.metainterp.resoperation import rop, opname
+from pypy.jit.backend.cli.methodfactory import get_method_wrapper
+
+System = CLR.System
+OpCodes = System.Reflection.Emit.OpCodes
+LoopDelegate = CLR.pypy.runtime.LoopDelegate
+InputArgs = CLR.pypy.runtime.InputArgs
+
+cVoid = ootype.nullruntimeclass
+
+
+class __extend__(AbstractValue):
+    __metaclass__ = extendabletype
+
+    def getCliType(self):
+        if self.type == history.INT:
+            return dotnet.typeof(System.Int32)
+        elif self.type == history.OBJ:
+            return dotnet.typeof(System.Object)
+        else:
+            assert False, 'Unknown type: %s' % self.type
+
+    def load(self, meth):
+        v = meth.var_for_box(self)
+        meth.il.Emit(OpCodes.Ldloc, v)
+
+    def store(self, meth):
+        v = meth.var_for_box(self)
+        meth.il.Emit(OpCodes.Stloc, v)
+
+
+class __extend__(Const):
+    __metaclass__ = extendabletype
+
+    def load(self, meth):
+        raise NotImplementedError
+
+    def store(self, meth):
+        assert False, 'cannot store() to Constant'
+
+
+class MethodArgument(AbstractValue):
+    def __init__(self, index, cliType):
+        self.index = index
+        self.cliType = cliType
+
+    def getCliType(self):
+        return self.cliType
+
+    def load(self, meth):
+        if self.index == 0:
+            meth.il.Emit(OpCodes.Ldarg_0)
+        elif self.index == 1:
+            meth.il.Emit(OpCodes.Ldarg_1)
+        elif self.index == 2:
+            meth.il.Emit(OpCodes.Ldarg_2)
+        elif self.index == 3:
+            meth.il.Emit(OpCodes.Ldarg_3)
+        else:
+            meth.il.Emit(OpCodes.Ldarg, self.index)
+
+    def store(self, meth):
+        meth.il.Emit(OpCodes.Starg, self.index)
+
+    def __repr__(self):
+        return "MethodArgument(%d)" % self.index
+
+
+class Method(object):
+
+    def __init__(self, cpu, name, loop):
+        self.cpu = cpu
+        self.name = name
+        self.loop = loop
+        self.boxes = {} # box --> local var
+        self.meth_wrapper = self._get_meth_wrapper()
+        self.il = self.meth_wrapper.get_il_generator()
+        self.av_consts = MethodArgument(0, System.Type.GetType("System.Object[]"))
+        self.av_inputargs = MethodArgument(1, dotnet.typeof(InputArgs))
+        self.emit_load_inputargs()
+        self.emit_operations()
+        self.emit_end()
+        delegatetype = dotnet.typeof(LoopDelegate)
+        consts = dotnet.new_array(System.Object, 0)
+        self.func = self.meth_wrapper.create_delegate(delegatetype, consts)
+
+
+    def _get_meth_wrapper(self):
+        restype = dotnet.class2type(cVoid)
+        args = self._get_args_array([dotnet.typeof(InputArgs)])
+        return get_method_wrapper(self.name, restype, args)
+
+    def _get_args_array(self, arglist):
+        array = dotnet.new_array(System.Type, len(arglist)+1)
+        array[0] = System.Type.GetType("System.Object[]")
+        for i in range(len(arglist)):
+            array[i+1] = arglist[i]
+        return array
+
+    def var_for_box(self, box):
+        try:
+            return self.boxes[box]
+        except KeyError:
+            v = self.il.DeclareLocal(box.getCliType())
+            self.boxes[box] = v
+            return v
+
+    def get_inputarg_field(self, type):
+        t = dotnet.typeof(InputArgs)
+        if type == history.INT:
+            fieldname = 'ints'
+        elif type == history.OBJ:
+            fieldname = 'objs'
+        else:
+            assert False, 'Unknown type %s' % type
+        return t.GetField(fieldname)        
+
+    def load_inputarg(self, i, type, clitype):
+        field = self.get_inputarg_field(type)
+        self.av_inputargs.load(self)
+        self.il.Emit(OpCodes.Ldfld, field)
+        self.il.Emit(OpCodes.Ldc_I4, i)
+        self.il.Emit(OpCodes.Ldelem, clitype)
+
+    def store_inputarg(self, i, type, clitype, valuebox):
+        field = self.get_inputarg_field(type)
+        self.av_inputargs.load(self)
+        self.il.Emit(OpCodes.Ldfld, field)
+        self.il.Emit(OpCodes.Ldc_I4, i)
+        valuebox.load(self)
+        self.il.Emit(OpCodes.Stelem, clitype)
+
+    def emit_load_inputargs(self):
+        i = 0
+        for box in self.loop.inputargs:
+            self.load_inputarg(i, box.type, box.getCliType())
+            box.store(self)
+            i+=1
+
+    def emit_operations(self):
+        for op in self.loop.operations:
+            if op.opnum == rop.INT_LSHIFT:
+                for box in op.args:
+                    box.load(self)
+                self.il.Emit(OpCodes.Shl)
+                op.result.store(self)
+            elif op.opnum == rop.FAIL:
+                i = 0
+                for box in op.args:
+                    self.store_inputarg(i, box.type,
+                                        box.getCliType(), box)
+                self.il.Emit(OpCodes.Ret)
+            else:
+                assert False, 'TODO'
+
+    def emit_end(self):
+        self.il.Emit(OpCodes.Ret)

Added: pypy/branch/pyjitpl5/pypy/jit/backend/cli/runner.py
==============================================================================
--- (empty file)
+++ pypy/branch/pyjitpl5/pypy/jit/backend/cli/runner.py	Mon May  4 14:40:54 2009
@@ -0,0 +1,81 @@
+from pypy.rpython.ootypesystem import ootype
+from pypy.jit.metainterp.history import AbstractDescr, AbstractMethDescr
+from pypy.jit.metainterp.history import Box, BoxInt, BoxObj
+from pypy.jit.metainterp import executor
+from pypy.jit.metainterp.resoperation import rop, opname
+from pypy.jit.backend import model
+from pypy.jit.backend.minimal.runner import cached_method
+from pypy.jit.backend.cli.method import Method
+from pypy.translator.cli import dotnet
+from pypy.translator.cli.dotnet import CLR
+
+System = CLR.System
+InputArgs = CLR.pypy.runtime.InputArgs
+
+
+class CliCPU(model.AbstractCPU):
+
+    is_oo = True
+
+    def __init__(self, rtyper, stats, translate_support_code=False,
+                 mixlevelann=None):
+        self.rtyper = rtyper
+        if rtyper:
+            assert rtyper.type_system.name == "ootypesystem"
+        self.stats = stats
+        self.translate_support_code = translate_support_code
+        self.inputargs = InputArgs()
+
+    @cached_method('_callcache')
+    def calldescrof(self, FUNC, ARGS, RESULT):
+        return StaticMethDescr(FUNC, ARGS, RESULT)
+
+    # ----------------------
+
+    def compile_operations(self, loop):
+        meth = Method(self, 'loop', loop)
+        loop._cli_meth = meth
+
+    def execute_operations(self, loop):
+        loop._cli_meth.func(self.inputargs)
+
+    def set_future_value_int(self, index, intvalue):
+        self.inputargs.ints[index] = intvalue
+
+    def set_future_value_obj(self, index, objvalue):
+        self.inputargs.objs[index] = objvalue
+
+    def get_latest_value_int(self, index):
+        return self.inputargs.ints[index]
+
+    def get_latest_value_obj(self, index):
+        return self.inputargs.objs[index]
+
+    # ----------------------
+
+    def do_call(self, args, calldescr):
+        assert isinstance(calldescr, StaticMethDescr)
+        funcbox, args = args[0], args[1:]
+        return calldescr.callfunc(funcbox, args)
+
+
+# ----------------------------------------------------------------------
+
+class StaticMethDescr(AbstractDescr):
+
+    def __init__(self, FUNC, ARGS, RESULT):
+        from pypy.jit.backend.llgraph.runner import boxresult, make_getargs
+        getargs = make_getargs(FUNC.ARGS)
+        def callfunc(funcbox, argboxes):
+            funcobj = ootype.cast_from_object(FUNC, funcbox.getobj())
+            funcargs = getargs(argboxes)
+            res = funcobj(*funcargs)
+            if RESULT is not ootype.Void:
+                return boxresult(RESULT, res)
+        self.callfunc = callfunc
+
+
+CPU = CliCPU
+
+import pypy.jit.metainterp.executor
+pypy.jit.metainterp.executor.make_execute_list(CPU)

Added: pypy/branch/pyjitpl5/pypy/jit/backend/cli/test/test_runner.py
==============================================================================
--- (empty file)
+++ pypy/branch/pyjitpl5/pypy/jit/backend/cli/test/test_runner.py	Mon May  4 14:40:54 2009
@@ -0,0 +1,36 @@
+import py
+from pypy.jit.backend.cli.runner import CliCPU
+from pypy.jit.backend.test.runner import OOtypeBackendTest
+
+class FakeStats(object):
+    pass
+
+# ____________________________________________________________
+
+class CliJitMixin(object):
+
+    typesystem = 'ootype'
+    CPUClass = CliCPU
+
+    # for the individual tests see
+    # ====> ../../test/runner.py
+    
+    def setup_class(cls):
+        cls.cpu = cls.CPUClass(rtyper=None, stats=FakeStats())
+
+    def _skip(self):
+        py.test.skip("not supported in non-translated version")
+
+    test_passing_guards = _skip      # GUARD_CLASS
+    test_failing_guards = _skip      # GUARD_CLASS
+
+
+class TestRunner(CliJitMixin, OOtypeBackendTest):
+
+    def skip(self):
+        py.test.skip('in-progress')
+
+    test_uint_rshift = skip
+    test_binary_operations = skip
+    test_unary_operations = skip
+    test_ovf_operations = skip

Modified: pypy/branch/pyjitpl5/pypy/jit/backend/minimal/runner.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/backend/minimal/runner.py	(original)
+++ pypy/branch/pyjitpl5/pypy/jit/backend/minimal/runner.py	Mon May  4 14:40:54 2009
@@ -678,20 +678,6 @@
         self.errbox = errbox
 
 
-class StaticMethDescr(AbstractDescr):
-
-    def __init__(self, FUNC, ARGS, RESULT):
-        from pypy.jit.backend.llgraph.runner import boxresult, make_getargs
-        getargs = make_getargs(FUNC.ARGS)
-        def callfunc(funcbox, argboxes):
-            funcobj = ootype.cast_from_object(FUNC, funcbox.getobj())
-            funcargs = getargs(argboxes)
-            res = funcobj(*funcargs)
-            if RESULT is not ootype.Void:
-                return boxresult(RESULT, res)
-        self.callfunc = callfunc
-
-
 class MethDescr(AbstractMethDescr):
     callmeth = None
     def __init__(self, SELFTYPE, methname):

Modified: pypy/branch/pyjitpl5/pypy/jit/backend/test/runner.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/backend/test/runner.py	(original)
+++ pypy/branch/pyjitpl5/pypy/jit/backend/test/runner.py	Mon May  4 14:40:54 2009
@@ -346,11 +346,11 @@
 class OOtypeBackendTest(BaseBackendTest):
 
     type_system = 'ootype'
-    Ptr = lambda x: x
+    Ptr = staticmethod(lambda x: x)
     FuncType = ootype.StaticMethod
     malloc = staticmethod(ootype.new)
     nullptr = staticmethod(ootype.null)
 
     @classmethod
     def get_funcbox(cls, cpu, func_ptr):
-        return ootype.cast_to_object(func_ptr)
+        return BoxObj(ootype.cast_to_object(func_ptr))

Modified: pypy/branch/pyjitpl5/pypy/translator/cli/src/pypylib.cs
==============================================================================
--- pypy/branch/pyjitpl5/pypy/translator/cli/src/pypylib.cs	(original)
+++ pypy/branch/pyjitpl5/pypy/translator/cli/src/pypylib.cs	Mon May  4 14:40:54 2009
@@ -109,6 +109,8 @@
 namespace pypy.runtime
 {
 
+    public delegate void LoopDelegate(InputArgs args);
+
     public class InputArgs {
       public int[] ints = new int[32];
       public float[] floats = new float[32];
@@ -134,6 +136,7 @@
       }
     }
 
+  /*
     public delegate uint FlexSwitchCase(uint block, InputArgs args);
 
     // XXX: there is a lot of code duplication between the next three classes,
@@ -268,6 +271,8 @@
         }
     }
 
+  */
+
     public class AutoSaveAssembly
     {
         private AssemblyBuilder assembly;



More information about the Pypy-commit mailing list