[pypy-svn] r20643 - in pypy/dist/pypy/rpython/l3interp: . test

arigo at codespeak.net arigo at codespeak.net
Sun Dec 4 16:43:14 CET 2005


Author: arigo
Date: Sun Dec  4 16:43:12 2005
New Revision: 20643

Modified:
   pypy/dist/pypy/rpython/l3interp/convertgraph.py
   pypy/dist/pypy/rpython/l3interp/test/test_convert.py
Log:
Adapted convertgraph to the new model.  Fun so far :-)


Modified: pypy/dist/pypy/rpython/l3interp/convertgraph.py
==============================================================================
--- pypy/dist/pypy/rpython/l3interp/convertgraph.py	(original)
+++ pypy/dist/pypy/rpython/l3interp/convertgraph.py	Sun Dec  4 16:43:12 2005
@@ -1,85 +1,131 @@
-from pypy.rpython.l3interp import model
 from pypy.rpython.l3interp import l3interp
+from pypy.rpython.l3interp import model
+from pypy.rpython.l3interp.model import Op
 from pypy.objspace.flow import model as flowmodel
+from pypy.rpython.lltypesystem import lltype
 
-def convert(entrygraph):
-    cvter = LL2L3Converter(entrygraph)
-    return cvter.globals
 
 class LL2L3Converter(object):
-    def __init__(self, entrygraph):
-        self.globals = model.Globals()
-        self.convert_graph(entrygraph)
+    def __init__(self):
+        pass
 
     def convert_graph(self, graph):
-        graph_cvter = LL2L3GraphConverter(graph, self)
-        l3graph = graph_cvter.l3graph
-        self.globals.graphs.append(l3graph)
-        return l3graph
-
-class LL2L3GraphConverter(object):
-    def __init__(self, graph, cvter):
-        self.cvter = cvter
-        self.graph = graph
-        self.blocks_ll2l3 = {}
-        self.constants_to_index = {}
-        self.constants = []
-        startlink = self.convert_startlink(graph.startblock)
-        self.l3graph = model.Graph(graph.name, startlink)
-        self.l3graph.constants_int = self.constants
-
-    def convert_startlink(self, block):
-        var_to_register = dict([(var, i)
-                                    for i, var in enumerate(block.inputargs)])
-        target = self.convert_block(block, var_to_register)
-        startlink = model.Link(target)
-        startlink.move_int_register = [i // 2
-            for i in range(len(block.inputargs) * 2)]
-        return startlink
-        
-    def convert_block(self, block, var_to_register):
-        if block in self.blocks_ll2l3:
-            return self.blocks_ll2l3[block]
-        def get_reg_number(var):
-            if var not in var_to_register:
-                var_to_register[var] = len(var_to_register)
-            return var_to_register[var]
-        l3ops = []
-        for op in block.operations:
-            l3ops.append(self.convert_op(op, get_reg_number))
-        assert block.exitswitch is None
-        l3block = model.Block()
-        self.blocks_ll2l3[block] = l3block
-        l3block.exitswitch = model.ONE_EXIT
-        l3block.exits = [self.convert_link(block.exits[0], var_to_register)]
-        l3block.operations = l3ops
+        l3block = convert_block(graph.startblock, {})
+        nargs = {'int': 0,
+                 'dbl': 0,
+                 'ptr': 0}
+        for v in graph.getargs():
+            nargs[getkind(v.concretetype)] += 1
+        return model.Graph(graph.name, l3block,
+                           nargs['int'], nargs['dbl'], nargs['ptr'])
+
+
+def getkind(T):
+    assert isinstance(T, lltype.LowLevelType)
+    if isinstance(T, lltype.Primitive):
+        if T == lltype.Float:
+            return 'dbl'
+        elif T == lltype.Void:
+            raise Exception("Void not implemented")
+        else:
+            return 'int'
+    else:
+        return 'ptr'
+
+def convert_block(block, memo):
+    if block in memo:
+        return memo[block]
+
+    stacksizes = {'int': 0,
+                  'dbl': 0,
+                  'ptr': 0}
+    constants = {'int': [],
+                 'dbl': [],
+                 'ptr': []}
+    var2stack = {}
+
+    def push(v):
+        kind = getkind(v.concretetype)
+        position = stacksizes[kind]
+        stacksizes[kind] += 1
+        var2stack[v] = position
+
+    def get(v):
+        kind = getkind(v.concretetype)
+        if isinstance(v, flowmodel.Constant):
+            clist = constants[kind]
+            try:
+                res = clist.index(v.value)
+            except ValueError:
+                res = len(clist)
+                clist.append(v.value)
+            return res
+        else:
+            position = var2stack[v]
+            return position - stacksizes[kind]    # < 0
+
+    for v in block.inputargs:
+        push(v)
+
+    insns = []
+    l3block = model.Block(insns)
+    memo[block] = l3block
+
+    if block.operations == ():
+        if len(block.inputargs) == 1:  # return block
+            if block.inputargs[0].concretetype is lltype.Void:
+                l3block.insns.append(Op.void_return)
+            else:
+                kind = getkind(block.inputargs[0].concretetype)
+                l3block.insns.append(model.very_low_level_opcode[
+                    {'int': 'int_return',
+                     'dbl': 'float_return',
+                     'ptr': 'adr_return'}[kind]])
+                l3block.insns.append(-1)
+        else:
+            raise NotImplementedError("except block")
         return l3block
 
-    def convert_link(self, link, var_to_register):
-        if link.target is self.graph.returnblock:
-            l3link = model.ReturnLink(var_to_register[link.args[0]])
-            return l3link
-        assert 0, "not yet implemented"
-
-    def convert_op(self, op, get_reg_number):
-        c_op = getattr(self, "op_" + op.opname, None)
-        if c_op is not None:
-            return c_op(op, get_reg_number)
-        l3args = []
-        for arg in op.args:
-            if isinstance(arg, flowmodel.Variable):
-                l3args.append(get_reg_number(arg))
-            else:
-                l3args.append(self.convert_const(arg))
-        l3op = model.Operation(getattr(l3interp.LLFrame, "op_" + op.opname),
-                               get_reg_number(op.result), l3args) 
-        return l3op
-
-    def convert_const(self, arg):
-        arg = int(arg.value)
-        if arg in self.constants_to_index:
-            return self.constants_to_index[arg]
-        index = len(self.constants)
-        self.constants.append(arg)
-        self.constants_to_index[arg] = index
-        return ~index
+    for spaceop in block.operations:
+        insns.append(model.very_low_level_opcode[spaceop.opname])
+        for v in spaceop.args:
+            insns.append(get(v))
+        if spaceop.result.concretetype is not lltype.Void:
+            push(spaceop.result)
+
+    def convert_link(link):
+        targetregs = {'int': [],
+                      'dbl': [],
+                      'ptr': []}
+        for v in link.args:
+            kind = getkind(v.concretetype)
+            targetregs[kind].append(get(v))
+        return model.Link(convert_block(link.target, memo),
+                          targetregs['int'] or None,
+                          targetregs['dbl'] or None,
+                          targetregs['ptr'] or None)
+
+    if block.exitswitch is None:
+        insns.append(Op.jump)
+        link, = block.exits
+        l3block.exit0 = convert_link(link)
+
+    elif block.exitswitch != flowmodel.Constant(flowmodel.last_exception):
+        link0, link1 = block.exits
+        if link0.exitcase:
+            link0, link1 = link1, link0
+        assert not link0.exitcase
+        assert link1.exitcase
+        insns.append(Op.jump_cond)
+        insns.append(get(block.exitswitch))
+        l3block.exit0 = convert_link(link0)
+        l3block.exit1 = convert_link(link1)
+
+    else:
+        raise NotImplementedError("exceptions")
+
+    if constants['int']: l3block.constants_int = constants['int']
+    if constants['dbl']: l3block.constants_dbl = constants['dbl']
+    if constants['ptr']: l3block.constants_ptr = constants['ptr']
+
+    return l3block

Modified: pypy/dist/pypy/rpython/l3interp/test/test_convert.py
==============================================================================
--- pypy/dist/pypy/rpython/l3interp/test/test_convert.py	(original)
+++ pypy/dist/pypy/rpython/l3interp/test/test_convert.py	Sun Dec  4 16:43:12 2005
@@ -3,14 +3,13 @@
 from pypy.translator.translator import TranslationContext
 
 def test_convert_add():
-    py.test.skip("in-progress")
     def f(x):
         return x + 4
     t = TranslationContext()
     t.buildannotator().build_types(f, [int])
     t.buildrtyper().specialize()
-    globals = convertgraph.convert(t.graphs[0])
-    interp = l3interp.LLInterpreter(globals)
-    graph = globals.graphs[0]
-    result = interp.eval_graph_int(graph, [0])
-    assert result == 4
+    conv = convertgraph.LL2L3Converter()
+    l3graph = conv.convert_graph(t.graphs[0])
+    result = l3interp.l3interpret(l3graph, [42], [], [])
+    assert isinstance(result, l3interp.L3Integer)
+    assert result.intval == 46



More information about the Pypy-commit mailing list