[pypy-svn] r32870 - in pypy/dist/pypy/translator/cli: . test
antocuni at codespeak.net
antocuni at codespeak.net
Wed Oct 4 14:58:21 CEST 2006
Author: antocuni
Date: Wed Oct 4 14:58:20 2006
New Revision: 32870
Added:
pypy/dist/pypy/translator/cli/stackopt.py (contents, props changed)
pypy/dist/pypy/translator/cli/test/test_stackopt.py (contents, props changed)
Modified:
pypy/dist/pypy/translator/cli/function.py
pypy/dist/pypy/translator/cli/gencli.py
pypy/dist/pypy/translator/cli/ilgenerator.py
pypy/dist/pypy/translator/cli/test/compile.py
Log:
A trivial implementation of the StackOptimizer: it simply optimizes
nothing so far :-)
Modified: pypy/dist/pypy/translator/cli/function.py
==============================================================================
--- pypy/dist/pypy/translator/cli/function.py (original)
+++ pypy/dist/pypy/translator/cli/function.py Wed Oct 4 14:58:20 2006
@@ -306,11 +306,11 @@
if v.name in self.argset:
selftype, selfname = self.args[0]
if self.is_method and v.name == selfname:
- self.ilasm.opcode('ldarg.0') # special case for 'self'
+ self.ilasm.load_self() # special case for 'self'
else:
- self.ilasm.opcode('ldarg', repr(v.name))
+ self.ilasm.load_arg(v)
else:
- self.ilasm.opcode('ldloc', repr(v.name))
+ self.ilasm.load_local(v)
elif isinstance(v, flowmodel.Constant):
self._load_const(v)
@@ -324,7 +324,7 @@
def store(self, v):
if isinstance(v, flowmodel.Variable):
if v.concretetype is not Void:
- self.ilasm.opcode('stloc', repr(v.name))
+ self.ilasm.store_local(v)
else:
assert False
Modified: pypy/dist/pypy/translator/cli/gencli.py
==============================================================================
--- pypy/dist/pypy/translator/cli/gencli.py (original)
+++ pypy/dist/pypy/translator/cli/gencli.py Wed Oct 4 14:58:20 2006
@@ -14,6 +14,9 @@
from pypy.translator.cli.rte import get_pypy_dll
from pypy.translator.cli.support import Tee
from pypy.translator.cli.prebuiltnodes import get_prebuilt_nodes
+from pypy.translator.cli.stackopt import StackOptGenerator
+
+USE_STACKOPT = True
class GenCli(object):
def __init__(self, tmpdir, translator, entrypoint=None, type_system_class=CTS,
@@ -42,8 +45,11 @@
if getoption('stdout'):
out = Tee(sys.stdout, out)
- self.ilasm = asm_class(out, self.assembly_name )
-
+ if USE_STACKOPT:
+ self.ilasm = StackOptGenerator(out, self.assembly_name)
+ else:
+ self.ilasm = asm_class(out, self.assembly_name)
+
# TODO: instance methods that are also called as unbound
# methods are rendered twice, once within the class and once
# as an external function. Fix this.
Modified: pypy/dist/pypy/translator/cli/ilgenerator.py
==============================================================================
--- pypy/dist/pypy/translator/cli/ilgenerator.py (original)
+++ pypy/dist/pypy/translator/cli/ilgenerator.py Wed Oct 4 14:58:20 2006
@@ -111,7 +111,7 @@
and method_type!='runtime')
def end_function(self):
- self.render()
+ self.flush()
self.code.closeblock()
def begin_try(self):
@@ -119,7 +119,7 @@
self.code.openblock()
def end_try(self):
- self.render()
+ self.flush()
self.code.closeblock()
def begin_catch(self, type_):
@@ -127,7 +127,7 @@
self.code.openblock()
def end_catch(self):
- self.render()
+ self.flush()
self.code.closeblock()
def locals(self, vars):
@@ -235,5 +235,5 @@
self.opcode('ldstr', string_literal(msg))
self.call_method('void class [mscorlib]System.IO.TextWriter::WriteLine(string)', virtual=True)
- def render(self):
+ def flush(self):
pass
Added: pypy/dist/pypy/translator/cli/stackopt.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/cli/stackopt.py Wed Oct 4 14:58:20 2006
@@ -0,0 +1,55 @@
+from pypy.translator.cli.ilgenerator import IlasmGenerator
+
+class StackOptMixin(object):
+ def __init__(self, *args):
+ self.super = super(StackOptMixin, self)
+ self.super.__init__(*args)
+ self._reset()
+
+ def _reset(self):
+ self.pending_ops = []
+
+ def opcode(self, op, *args):
+ self.pending_ops.append((op, args))
+
+ def writeline(self, s=''):
+ self.pending_ops.append(('WRITELINE', (s,)))
+
+ def write(self, s, indent=0):
+ self.pending_ops.append(('WRITE', (s, indent)))
+
+ def _optimize(self):
+ pass
+
+ def do_load(self, vartype, var):
+ if vartype == 'local':
+ self.super.load_local(var)
+ elif vartype == 'arg':
+ self.super.load_arg(var)
+ elif vartype == 'self':
+ assert var is None
+ self.super.load_self()
+ else:
+ assert False
+
+ def do_store(self, vartype, var):
+ assert vartype == 'local'
+ self.super.store_local(var)
+
+ def do_opcode(self, opcode, *args):
+ self.super.opcode(opcode, *args)
+
+ def flush(self):
+ self._optimize()
+ for opcode, args in self.pending_ops:
+ if opcode == 'WRITELINE':
+ self.super.writeline(*args)
+ elif opcode == 'WRITE':
+ self.super.write(*args)
+ else:
+ self.super.opcode(opcode, *args)
+ self._reset()
+
+class StackOptGenerator(StackOptMixin, IlasmGenerator):
+ pass
+
Modified: pypy/dist/pypy/translator/cli/test/compile.py
==============================================================================
--- pypy/dist/pypy/translator/cli/test/compile.py (original)
+++ pypy/dist/pypy/translator/cli/test/compile.py Wed Oct 4 14:58:20 2006
@@ -28,16 +28,13 @@
def __init__(self, x):
self.x = x
-def foo(a, b):
- pass
+def foo(a, b, c):
+ return c,b,a
mylist = [1,2,3]
def bar(x, y):
- if x:
- return mylist
- else:
- return []
+ return foo(x+y, x-y, x*y)
f = compile_function(bar, [int, int])
Added: pypy/dist/pypy/translator/cli/test/test_stackopt.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/cli/test/test_stackopt.py Wed Oct 4 14:58:20 2006
@@ -0,0 +1,50 @@
+from pypy.translator.cli.stackopt import StackOptMixin
+
+class FakeGenerator(object):
+ def __init__(self, *args):
+ self.lines = ['']
+ self.opcodes = []
+
+ def opcode(self, opcode, *args):
+ self.opcodes.append((opcode, args))
+ self.lines[-1] += '%s %s' % (opcode, ' '.join(args))
+ self.lines.append('')
+
+ def write(self, s, index=0):
+ self.lines[-1] += s
+
+ def writeline(self, s=''):
+ self.lines[-1] += s
+ self.lines.append('')
+
+ def get_string(self):
+ return '\n'.join(self.lines[:-1])
+
+class TestStackOpt(StackOptMixin, FakeGenerator):
+ pass
+
+
+def test_code_generation():
+ ilasm = TestStackOpt()
+ ilasm.write('.method public static void foo()')
+ ilasm.writeline(' {')
+ ilasm.opcode('ldc.i4.0')
+ ilasm.opcode('pop')
+ ilasm.opcode('ret')
+ ilasm.writeline('}')
+ ilasm.flush()
+ s = ilasm.get_string()
+ assert s.strip() == """
+.method public static void foo() {
+ldc.i4.0
+pop
+ret
+}
+""".strip()
+
+def test_opcodes():
+ ilasm = TestStackOpt()
+ ilasm.opcode('ldloc', 'x')
+ ilasm.opcode('ldloc', 'y')
+ ilasm.flush()
+ assert ilasm.opcodes == [('ldloc', ('x',)), ('ldloc', ('y',))]
More information about the Pypy-commit
mailing list