[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