[pypy-svn] r79283 - in pypy/trunk/pypy: objspace/flow objspace/flow/test translator translator/backendopt translator/backendopt/test
fijal at codespeak.net
fijal at codespeak.net
Fri Nov 19 19:13:08 CET 2010
Author: fijal
Date: Fri Nov 19 19:13:06 2010
New Revision: 79283
Modified:
pypy/trunk/pypy/objspace/flow/model.py
pypy/trunk/pypy/objspace/flow/test/test_objspace.py
pypy/trunk/pypy/translator/backendopt/mallocprediction.py
pypy/trunk/pypy/translator/backendopt/mallocv.py
pypy/trunk/pypy/translator/backendopt/raisingop2direct_call.py
pypy/trunk/pypy/translator/backendopt/removenoops.py
pypy/trunk/pypy/translator/backendopt/storesink.py
pypy/trunk/pypy/translator/backendopt/support.py
pypy/trunk/pypy/translator/backendopt/test/test_ssa.py
pypy/trunk/pypy/translator/exceptiontransform.py
pypy/trunk/pypy/translator/simplify.py
Log:
make SpaceOperations consume less space by making them specialized on exact number of arguments.
Saves a bit of space and a bit of time when annotating.
Modified: pypy/trunk/pypy/objspace/flow/model.py
==============================================================================
--- pypy/trunk/pypy/objspace/flow/model.py (original)
+++ pypy/trunk/pypy/objspace/flow/model.py Fri Nov 19 19:13:06 2010
@@ -226,7 +226,7 @@
assert isinstance(a, Variable), a
self.inputargs = [mapping.get(a, a) for a in self.inputargs]
for op in self.operations:
- op.args = [mapping.get(a, a) for a in op.args]
+ op.args = tuple([mapping.get(a, a) for a in op.args])
op.result = mapping.get(op.result, op.result)
self.exitswitch = mapping.get(self.exitswitch, self.exitswitch)
for link in self.exits:
@@ -329,13 +329,17 @@
"""Attempted wrapping of a type that cannot sanely appear in flow graph or
during its construction"""
-
class SpaceOperation(object):
__slots__ = "opname args result offset".split()
+ def __new__(cls, opname, args, result, offset=-1):
+ if opname == 'direct_call':
+ assert isinstance(args[0], Constant)
+ cls = globals().get('SpaceOperation' + str(len(args)), SpaceOperationN)
+ return object.__new__(cls, opname, args, result, offset)
def __init__(self, opname, args, result, offset=-1):
self.opname = intern(opname) # operation name
- self.args = list(args) # mixed list of var/const
+ self.args = tuple(args) # mixed list of var/const
self.result = result # either Variable or Constant instance
self.offset = offset # offset in code string
@@ -355,6 +359,58 @@
return "%r = %s(%s)" % (self.result, self.opname,
", ".join(map(repr, self.args)))
+ def getargs(self):
+ raise NotImplementedError
+ def setargs(self, args):
+ raise NotImplementedError
+ args = property(getargs, setargs)
+
+class SpaceOperation0(SpaceOperation):
+ __slots__ = "opname result offset".split()
+
+ def getargs(self):
+ return ()
+ def setargs(self, args):
+ assert not args
+ args = property(getargs, setargs)
+
+class SpaceOperation1(SpaceOperation):
+ __slots__ = "opname result offset arg0".split()
+
+ def getargs(self):
+ return (self.arg0,)
+ def setargs(self, args):
+ self.arg0, = args
+ args = property(getargs, setargs)
+
+class SpaceOperation2(SpaceOperation):
+ __slots__ = "opname result offset arg0 arg1".split()
+
+ def getargs(self):
+ return (self.arg0, self.arg1)
+ def setargs(self, args):
+ self.arg0, self.arg1 = args
+ args = property(getargs, setargs)
+
+class SpaceOperation3(SpaceOperation):
+ __slots__ = "opname result offset arg0 arg1 arg2".split()
+
+ def getargs(self):
+ return (self.arg0, self.arg1, self.arg2)
+ def setargs(self, args):
+ self.arg0, self.arg1, self.arg2 = args
+ args = property(getargs, setargs)
+
+class SpaceOperationN(SpaceOperation):
+ __slots__ = "opname result offset _args".split()
+
+ def getargs(self):
+ return self._args
+ def setargs(self, args):
+ assert isinstance(args, tuple)
+ self._args = args
+ args = property(getargs, setargs)
+
class Atom(object):
def __init__(self, name):
self.__name__ = name # make save_global happy
Modified: pypy/trunk/pypy/objspace/flow/test/test_objspace.py
==============================================================================
--- pypy/trunk/pypy/objspace/flow/test/test_objspace.py (original)
+++ pypy/trunk/pypy/objspace/flow/test/test_objspace.py Fri Nov 19 19:13:06 2010
@@ -373,9 +373,9 @@
ops = x.startblock.operations
assert len(ops) == 2
assert ops[0].opname == 'simple_call'
- assert ops[0].args == [Constant(IndexError)]
+ assert ops[0].args == (Constant(IndexError),)
assert ops[1].opname == 'type'
- assert ops[1].args == [ops[0].result]
+ assert ops[1].args == (ops[0].result,)
assert x.startblock.exits[0].args == [ops[1].result, ops[0].result]
assert x.startblock.exits[0].target is x.exceptblock
Modified: pypy/trunk/pypy/translator/backendopt/mallocprediction.py
==============================================================================
--- pypy/trunk/pypy/translator/backendopt/mallocprediction.py (original)
+++ pypy/trunk/pypy/translator/backendopt/mallocprediction.py Fri Nov 19 19:13:06 2010
@@ -80,7 +80,7 @@
graphvars = [None] * len(op.args)
else:
graphvars = called_graph.getargs() + [called_graph.getreturnvar()]
- for var, graphvar in zip(op.args[1:] + [op.result], graphvars):
+ for var, graphvar in zip(op.args[1:] + (op.result,), graphvars):
varstate = adi.getstate(var)
if varstate is None:
#print "no varstate"
Modified: pypy/trunk/pypy/translator/backendopt/mallocv.py
==============================================================================
--- pypy/trunk/pypy/translator/backendopt/mallocv.py (original)
+++ pypy/trunk/pypy/translator/backendopt/mallocv.py Fri Nov 19 19:13:06 2010
@@ -980,7 +980,7 @@
def handle_op_indirect_call(self, op):
v_func = self.rename_nonvirtual(op.args[0], op)
if isinstance(v_func, Constant):
- op = SpaceOperation('direct_call', [v_func] + op.args[1:-1],
+ op = SpaceOperation('direct_call', (v_func,) + op.args[1:-1],
op.result)
return self.handle_op_direct_call(op)
else:
Modified: pypy/trunk/pypy/translator/backendopt/raisingop2direct_call.py
==============================================================================
--- pypy/trunk/pypy/translator/backendopt/raisingop2direct_call.py (original)
+++ pypy/trunk/pypy/translator/backendopt/raisingop2direct_call.py Fri Nov 19 19:13:06 2010
@@ -1,5 +1,6 @@
from pypy.translator.backendopt.support import log, all_operations, annotate
import pypy.rpython.raisingops.raisingops
+from pypy.objspace.flow.model import SpaceOperation
log = log.raisingop2directcall
def is_raisingop(op):
@@ -26,7 +27,7 @@
log('starting')
seen = {}
- for op in all_operations(graphs):
+ for block, i, op in all_operations(graphs):
if not is_raisingop(op):
continue
func = getattr(pypy.rpython.raisingops.raisingops, op.opname, None)
@@ -36,8 +37,10 @@
if op.opname not in seen:
seen[op.opname] = 0
seen[op.opname] += 1
- op.args.insert(0, annotate(translator, func, op.result, op.args))
- op.opname = 'direct_call'
+ arg = annotate(translator, func, op.result, op.args)
+ block.operations[i] = SpaceOperation('direct_call',
+ (arg,) + op.args,
+ op.result, i)
#statistics...
for k, v in seen.iteritems():
@@ -55,7 +58,7 @@
# op.opname += '_'
#selfdiagnostics... assert that there are no more raisingops
- for op in all_operations(graphs):
+ for block, i, op in all_operations(graphs):
if is_raisingop(op):
log.warning("%s not transformed" % op.opname)
Modified: pypy/trunk/pypy/translator/backendopt/removenoops.py
==============================================================================
--- pypy/trunk/pypy/translator/backendopt/removenoops.py (original)
+++ pypy/trunk/pypy/translator/backendopt/removenoops.py Fri Nov 19 19:13:06 2010
@@ -23,7 +23,7 @@
if op is not None:
for i in range(len(op.args)):
if op.args[i] == op_result:
- op.args[i] = op_arg
+ op.args = op.args[:i] + (op_arg,) + op.args[i + 1:]
if (op.opname == "indirect_call"
and isinstance(op.args[0], Constant)):
op.opname = "direct_call"
Modified: pypy/trunk/pypy/translator/backendopt/storesink.py
==============================================================================
--- pypy/trunk/pypy/translator/backendopt/storesink.py (original)
+++ pypy/trunk/pypy/translator/backendopt/storesink.py Fri Nov 19 19:13:06 2010
@@ -1,6 +1,7 @@
from pypy.rpython.lltypesystem.lloperation import llop
from pypy.translator.backendopt import removenoops
+from pypy.objspace.flow.model import SpaceOperation
def has_side_effects(op):
if op.opname == 'debug_assert':
@@ -22,13 +23,12 @@
for block in graph.iterblocks():
newops = []
cache = {}
- for op in block.operations:
+ for i, op in enumerate(block.operations):
if op.opname == 'getfield':
tup = (op.args[0], op.args[1].value)
res = cache.get(tup, None)
if res is not None:
- op.opname = 'same_as'
- op.args = [res]
+ op = SpaceOperation('same_as', [res], op.result, i)
added_some_same_as = True
else:
cache[tup] = op.result
Modified: pypy/trunk/pypy/translator/backendopt/support.py
==============================================================================
--- pypy/trunk/pypy/translator/backendopt/support.py (original)
+++ pypy/trunk/pypy/translator/backendopt/support.py Fri Nov 19 19:13:06 2010
@@ -21,8 +21,8 @@
def all_operations(graphs):
for graph in graphs:
for block in graph.iterblocks():
- for op in block.operations:
- yield op
+ for i, op in enumerate(block.operations):
+ yield block, i, op
def annotate(translator, func, result, args):
args = [arg.concretetype for arg in args]
Modified: pypy/trunk/pypy/translator/backendopt/test/test_ssa.py
==============================================================================
--- pypy/trunk/pypy/translator/backendopt/test/test_ssa.py (original)
+++ pypy/trunk/pypy/translator/backendopt/test/test_ssa.py Fri Nov 19 19:13:06 2010
@@ -75,7 +75,7 @@
assert len(b2.inputargs) == 2
assert len(b3.inputargs) == 2
- assert b2.inputargs == b2.operations[0].args
+ assert b2.inputargs == list(b2.operations[0].args)
assert len(b1.exits[0].args) == 2
assert b1.exits[0].args[1] is c
assert len(b2.exits[0].args) == 2
Modified: pypy/trunk/pypy/translator/exceptiontransform.py
==============================================================================
--- pypy/trunk/pypy/translator/exceptiontransform.py (original)
+++ pypy/trunk/pypy/translator/exceptiontransform.py Fri Nov 19 19:13:06 2010
@@ -234,33 +234,39 @@
def replace_stack_unwind(self, block):
for i in range(len(block.operations)):
- if block.operations[i].opname == 'stack_unwind':
+ op = block.operations[i]
+ if op.opname == 'stack_unwind':
# if there are stack_unwind ops left,
# the graph was not stackless-transformed
# so we need to raise a StackOverflow in any
# case
- block.operations[i].opname = "direct_call"
- block.operations[i].args = [self.rpyexc_raise_stack_overflow_ptr]
+ args = [self.rpyexc_raise_stack_overflow_ptr]
+ block.operations[i] = SpaceOperation('direct_call',
+ args, op.result, i)
def replace_fetch_restore_operations(self, block):
# the gctransformer will create these operations. It looks as if the
# order of transformations is important - but the gctransformer will
# put them in a new graph, so all transformations will run again.
for i in range(len(block.operations)):
- opname = block.operations[i].opname
+ op = block.operations[i]
+ opname = op.opname
if opname == 'gc_fetch_exception':
- block.operations[i].opname = "direct_call"
- block.operations[i].args = [self.rpyexc_fetch_exception_ptr]
-
+ args = [self.rpyexc_fetch_exception_ptr]
+ block.operations[i] = SpaceOperation('direct_call', args,
+ op.result, i)
elif opname == 'gc_restore_exception':
- block.operations[i].opname = "direct_call"
- block.operations[i].args.insert(0, self.rpyexc_restore_exception_ptr)
+ args = (self.rpyexc_restore_exception_ptr,) + op.args
+ block.operations[i] = SpaceOperation('direct_call', args,
+ op.result, i)
elif opname == 'get_exception_addr': # only for lltype
- block.operations[i].opname = "direct_call"
- block.operations[i].args.insert(0, self.rpyexc_get_exception_addr_ptr)
+ args = (self.rpyexc_get_exception_addr_ptr,) + op.args
+ block.operations[i] = SpaceOperation('direct_call', args,
+ op.result, i)
elif opname == 'get_exc_value_addr': # only for lltype
- block.operations[i].opname = "direct_call"
- block.operations[i].args.insert(0, self.rpyexc_get_exc_value_addr_ptr)
+ args = (self.rpyexc_get_exc_value_addr_ptr,) + op.args
+ block.operations[i] = SpaceOperation('direct_call', args,
+ op.result, i)
def transform_block(self, graph, block):
need_exc_matching = False
Modified: pypy/trunk/pypy/translator/simplify.py
==============================================================================
--- pypy/trunk/pypy/translator/simplify.py (original)
+++ pypy/trunk/pypy/translator/simplify.py Fri Nov 19 19:13:06 2010
@@ -146,8 +146,9 @@
del block.operations[i]
block.renamevariables({op.result: op1.result})
elif op.args[0] == covfls:
- op.opname = 'lshift_ovf'
- del op.args[0]
+ block.operations[i] = SpaceOperation('lshift_ovf',
+ op.args[1:], op.result,
+ i)
def simplify_exceptions(graph):
"""The exception handling caused by non-implicit exceptions
@@ -293,14 +294,13 @@
def rename(v):
return renaming.get(v, v)
def rename_op(op):
+ opname = op.opname
args = [rename(a) for a in op.args]
- op = SpaceOperation(op.opname, args, rename(op.result), op.offset)
- # special case...
- if op.opname == 'indirect_call':
- if isinstance(op.args[0], Constant):
- assert isinstance(op.args[-1], Constant)
- del op.args[-1]
- op.opname = 'direct_call'
+ if (opname == 'indirect_call' and
+ isinstance(args[0], Constant)):
+ opname = 'direct_call'
+ del args[-1]
+ op = SpaceOperation(opname, args, rename(op.result), op.offset)
return op
for op in link.target.operations:
link.prevblock.operations.append(rename_op(op))
More information about the Pypy-commit
mailing list