[pypy-svn] r32919 - in pypy/dist/pypy/translator/cli: . test
antocuni at codespeak.net
antocuni at codespeak.net
Thu Oct 5 21:06:05 CEST 2006
Author: antocuni
Date: Thu Oct 5 21:06:04 2006
New Revision: 32919
Modified:
pypy/dist/pypy/translator/cli/ilgenerator.py
pypy/dist/pypy/translator/cli/stackopt.py
pypy/dist/pypy/translator/cli/test/test_stackopt.py
Log:
Minor stackopt improvements.
Modified: pypy/dist/pypy/translator/cli/ilgenerator.py
==============================================================================
--- pypy/dist/pypy/translator/cli/ilgenerator.py (original)
+++ pypy/dist/pypy/translator/cli/ilgenerator.py Thu Oct 5 21:06:04 2006
@@ -99,6 +99,7 @@
def begin_function(self, name, arglist, returntype, is_entrypoint = False, *args, **kwds):
# TODO: .maxstack
+ self.func_name = name
runtime = kwds.get('runtime', False)
if runtime:
method_type = 'runtime'
@@ -141,9 +142,9 @@
self.writeline(')')
def label(self, lbl):
- self.writeline()
- self.write(lbl + ':', indent=-1)
- self.writeline()
+ self.code.writeline()
+ self.code.write(lbl + ':', indent=-1)
+ self.code.writeline()
def leave(self, lbl):
self.opcode('leave', lbl)
@@ -160,7 +161,7 @@
self.opcode(opcode, lbl)
def call(self, func):
- self.opcode('call ', func)
+ self.opcode('call', func)
def call_method(self, meth, virtual):
if virtual:
Modified: pypy/dist/pypy/translator/cli/stackopt.py
==============================================================================
--- pypy/dist/pypy/translator/cli/stackopt.py (original)
+++ pypy/dist/pypy/translator/cli/stackopt.py Thu Oct 5 21:06:04 2006
@@ -1,9 +1,7 @@
from pypy.translator.cli.ilgenerator import IlasmGenerator
class StackOptMixin(object):
- LOADS = set(['ldloc', 'ldarg']) # maybe ldarg.0?
- STORES = set(['stloc'])
-
+
def __init__(self, *args):
self.super = super(StackOptMixin, self)
self.super.__init__(*args)
@@ -28,38 +26,69 @@
def closeblock(self):
self.pending_ops.append(('SUPER', ('closeblock',)))
+ def label(self, lbl):
+ self.pending_ops.append(('LABEL', (lbl,)))
+
+ def _varname(self, op, args):
+ if op in ('ldloc', 'ldarg', 'stloc'):
+ return args[0]
+ elif op.startswith('ld'):
+ return ('PLACEHOLDER', op, args)
+ else:
+ assert False, "undefined varname of %s" % op
+
+ def _is_load(self, op):
+ return op is not None and op.startswith('ld')
+
+ def _is_simple_load(self, op):
+ return op is not None and (op.startswith('ldloc') or
+ op.startswith('ldarg') or
+ op.startswith('ldsfld') or
+ op.startswith('ldc'))
+
def _optimize(self):
+ self._collect_stats()
+ self._remove_renaming()
+
+ def _collect_stats(self):
assign_count = {}
read_count = {}
- for op, args in self.pending_ops:
- if op in self.STORES:
+ for item in self.pending_ops:
+ if item is None:
+ continue
+ op, args = item
+ if op == 'stloc':
varname, = args
assign_count[varname] = assign_count.get(varname, 0) + 1
- elif op in self.LOADS:
+ elif op == 'ldloc':
varname, = args
read_count[varname] = read_count.get(varname, 0) + 1
+ self.assign_count = assign_count
+ self.read_count = read_count
+ def _remove_renaming(self):
+ assign_count = self.assign_count
+ read_count = self.read_count
prev_op, prev_args = None, None
for i, (op, args) in enumerate(self.pending_ops):
- if op in self.STORES and prev_op in self.LOADS:
+ if op == 'stloc' and self._is_simple_load(prev_op):
# ldloc x, stloc x0 --> remove both, map x0 to x
varname, = args
if assign_count[varname] == 1:
- self.mapping[varname] = self.mapping.get(prev_args[0], (prev_op, prev_args))
+ self.mapping[varname] = self.mapping.get(self._varname(prev_op, prev_args), (prev_op, prev_args))
self.pending_ops[i-1] = None
self.pending_ops[i] = None
op, args = None, None # to prevent the next opcode thinking the previous was a store
- elif op in self.LOADS:
- if prev_op in self.STORES and args == prev_args and read_count[args[0]] == 1:
+ elif op == 'ldloc':
+ if prev_op == 'stloc' and args == prev_args and read_count[args[0]] == 1:
# stloc x, ldloc x --> remove both
self.pending_ops[i-1] = None
self.pending_ops[i] = None
op, args = None, None # to prevent the next opcode thinking the previous was a load
else:
# ldloc x, stloc x1, ..., ldloc x1 --> ..., ldloc x
- varname, = args
try:
- self.pending_ops[i] = self.mapping[varname]
+ self.pending_ops[i] = self.mapping[self._varname(op, args)]
except KeyError:
pass
prev_op, prev_args = op, args
@@ -73,6 +102,8 @@
if opcode == 'SUPER':
method = args[0]
getattr(self.super, method)(*args[1:])
+ elif opcode == 'LABEL':
+ self.super.label(*args)
else:
self.super.opcode(opcode, *args)
self._reset()
Modified: pypy/dist/pypy/translator/cli/test/test_stackopt.py
==============================================================================
--- pypy/dist/pypy/translator/cli/test/test_stackopt.py (original)
+++ pypy/dist/pypy/translator/cli/test/test_stackopt.py Thu Oct 5 21:06:04 2006
@@ -99,3 +99,12 @@
ilasm.opcode('ldloc', 'x')
ilasm.flush()
assert ilasm.opcodes[0] == ('stloc', ('x',))
+
+def test_ldarg0():
+ ilasm = TestStackOpt()
+ ilasm.opcode('ldarg.0')
+ ilasm.opcode('stloc', 'x')
+ ilasm.opcode('ldloc', 'x')
+ ilasm.flush()
+ assert ilasm.opcodes == [('ldarg.0', ())]
+
More information about the Pypy-commit
mailing list