[pypy-svn] r17903 - in pypy/dist/pypy/translator: backendopt backendopt/test llvm llvm/backendopt llvm/module
ericvrp at codespeak.net
ericvrp at codespeak.net
Tue Sep 27 15:33:12 CEST 2005
Author: ericvrp
Date: Tue Sep 27 15:33:10 2005
New Revision: 17903
Added:
pypy/dist/pypy/translator/backendopt/removezerobytemalloc.py
pypy/dist/pypy/translator/backendopt/test/test_removezerobytemalloc.py
pypy/dist/pypy/translator/llvm/backendopt/mergemallocs.py
pypy/dist/pypy/translator/llvm/backendopt/removeexcmallocs.py
Modified:
pypy/dist/pypy/translator/backendopt/all.py
pypy/dist/pypy/translator/llvm/exception.py
pypy/dist/pypy/translator/llvm/funcnode.py
pypy/dist/pypy/translator/llvm/genllvm.py
pypy/dist/pypy/translator/llvm/module/extfunction.py
Log:
working on experimental transformations. disabled for now!
Modified: pypy/dist/pypy/translator/backendopt/all.py
==============================================================================
--- pypy/dist/pypy/translator/backendopt/all.py (original)
+++ pypy/dist/pypy/translator/backendopt/all.py Tue Sep 27 15:33:10 2005
@@ -4,23 +4,34 @@
from pypy.translator.backendopt.malloc import remove_simple_mallocs
from pypy.translator.backendopt.ssa import SSI_to_SSA
from pypy.translator.backendopt.propagate import propagate_all
+from pypy.translator.backendopt.removezerobytemalloc import remove_zero_byte_mallocs
from pypy.translator import simplify
def backend_optimizations(translator, inline_threshold=1,
mallocs=True,
ssa_form=True,
- propagate=False):
+ propagate=False,
+ removezerobytemallocs=False):
# remove obvious no-ops
for graph in translator.flowgraphs.values():
remove_same_as(graph)
simplify.eliminate_empty_blocks(graph)
simplify.transform_dead_op_vars(graph, translator)
- # inline functions in each other
+
+ # remove allocation of empty structs
+ if removezerobytemallocs:
+ for graph in translator.flowgraphs.values():
+ remove_zero_byte_mallocs(graph)
+
+ # ...
if propagate:
propagate_all(translator)
+
+ # inline functions in each other
if inline_threshold:
auto_inlining(translator, inline_threshold)
+
# vaporize mallocs
if mallocs:
for graph in translator.flowgraphs.values():
Added: pypy/dist/pypy/translator/backendopt/removezerobytemalloc.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/backendopt/removezerobytemalloc.py Tue Sep 27 15:33:10 2005
@@ -0,0 +1,16 @@
+from pypy.objspace.flow.model import Constant, Block, flatten
+from pypy.objspace.flow.model import SpaceOperation
+from pypy.rpython import lltype
+
+def remove_zero_byte_mallocs(graph):
+ blocks = [x for x in flatten(graph) if isinstance(x, Block)]
+ for block in blocks:
+ for i, op in enumerate(block.operations):
+ if op.opname != 'malloc':
+ continue
+ arg = op.args[0].value
+ if True: #isinstance(arg, lltype.Struct) and arg._names_without_voids() == []:
+ print 'remove_zero_byte_mallocs: removed malloc(%s) from previous line' % arg
+ nullresulttype = op.result.concretetype
+ nullresult = Constant(nullresulttype._defl(), nullresulttype)
+ block.operations[i] = SpaceOperation('cast_null_to_ptr', [nullresult], op.result)
Added: pypy/dist/pypy/translator/backendopt/test/test_removezerobytemalloc.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/backendopt/test/test_removezerobytemalloc.py Tue Sep 27 15:33:10 2005
@@ -0,0 +1,21 @@
+from pypy.objspace.flow.model import traverse, Block, Link, Variable, Constant
+from pypy.translator.backendopt.removezerobytemalloc import remove_zero_byte_mallocs
+from pypy.translator.translator import Translator
+from pypy.rpython.llinterp import LLInterpreter
+from pypy.translator.test.snippet import is_perfect_number
+
+def test_removezerobytemalloc():
+ x = ()
+ def func2(q):
+ return q
+ def zerobytemalloc():
+ y = func2(x)
+ return len(x)
+ t = Translator(zerobytemalloc)
+ a = t.annotate([])
+ t.specialize()
+ remove_zero_byte_mallocs(t.flowgraphs[zerobytemalloc])
+ #t.view()
+ lli = LLInterpreter(t.flowgraphs, t.rtyper)
+ res = lli.eval_function(zerobytemalloc, ())
+ assert res == 0
Added: pypy/dist/pypy/translator/llvm/backendopt/mergemallocs.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/llvm/backendopt/mergemallocs.py Tue Sep 27 15:33:10 2005
@@ -0,0 +1,22 @@
+from pypy.objspace.flow.model import Block, flatten, SpaceOperation
+
+
+def merge_mallocs(translator, graph):
+ """Merge all mallocs of identical in a block into one.
+ Thus all mallocs of atomic data are merged and all mallocs of
+ non-atomic data are also merged into one. This reasoning behind this is
+ that data allocated in the same block will probably have about the same
+ livespan. So we hope that this does not increase the memory appetite
+ of your program by much.
+
+ warning: some will consider this a dirty hack, that's ok! :)
+ """
+ blocks = [x for x in flatten(graph) if isinstance(x, Block)]
+ for block in blocks:
+ n_mallocs_in_block = 0
+ for op in block.operations:
+ if op.opname != 'malloc':
+ continue
+ n_mallocs_in_block += 1
+ if n_mallocs_in_block >= 2:
+ print 'merge_mallocs: n_mallocs_in_block=%d' % n_mallocs_in_block
Added: pypy/dist/pypy/translator/llvm/backendopt/removeexcmallocs.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/llvm/backendopt/removeexcmallocs.py Tue Sep 27 15:33:10 2005
@@ -0,0 +1,37 @@
+from pypy.objspace.flow.model import Block, Constant, flatten, SpaceOperation
+from pypy.translator.backendopt.inline import _find_exception_type
+
+
+def _llvm_structsize(struct):
+ #XXX TODO take a save guess
+ return 16
+
+def remove_exception_mallocs(translator, graph, ringbuffer_entry_maxsize=16, ringbuffer_n_entries=1024):
+ """Remove mallocs that occur because an exception is raised.
+ Typically this data is shortlived and occuring often in highlevel
+ languages like Python. So it would be preferable if we would not need
+ to call a malloc function. We can not allocate the data on the stack
+ because a global pointer (last_exception_type) is pointing to it.
+
+ Here we use a ringbuffer of fixed size to contain exception instances.
+ Our ringbuffer entries have fixed (maximum)size so all malloc over that
+ amount are not affected by this code.
+
+ warning: this code will not work when your code references
+ an exception instance 'long' after it has been raised.
+ """
+ blocks = [x for x in flatten(graph) if isinstance(x, Block)]
+ for block in blocks:
+ ops = block.operations
+ if (len(ops) < 3 or
+ ops[0].opname != 'malloc' or ops[1].opname != 'cast_pointer' or
+ ops[2].opname != 'setfield' or ops[2].args[1].value != 'typeptr' or
+ not isinstance(ops[2].args[1], Constant) or
+ _llvm_structsize(ops[0].args[0]) > ringbuffer_entry_maxsize): #todo: ops[2].args[2] to vtable
+ continue
+ print 'remove_exception_malloc: ', str(ops[0].args[0]), ops[2].args[2]
+ #ops = [SpaceOperation('ops[0].result = load sbyte** %exception_ringbuffer'),
+ # SpaceOperation('%tmpptr.0 = add sbyte* ops[0].result, ringbuffer_entry_maxsize'),
+ # SpaceOperation('%tmpptr.1 = and sbyte* tmpptr.0, ~(ringbuffer_n_entries*ringbuffer_entry_maxsize)'),
+ # SpaceOperation('store sbyte* %tmpptr.1, sbyte** %exception_ringbuffer),
+ # ops[1:]]
Modified: pypy/dist/pypy/translator/llvm/exception.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/exception.py (original)
+++ pypy/dist/pypy/translator/llvm/exception.py Tue Sep 27 15:33:10 2005
@@ -2,6 +2,9 @@
class ExceptionPolicy:
+ RINGBUFFER_ENTRY_MAXSIZE = 16
+ RINGBUGGER_N_ENTRIES = 1024
+
def __init__(self):
raise Exception, 'ExceptionPolicy should not be used directly'
Modified: pypy/dist/pypy/translator/llvm/funcnode.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/funcnode.py (original)
+++ pypy/dist/pypy/translator/llvm/funcnode.py Tue Sep 27 15:33:10 2005
@@ -5,6 +5,8 @@
from pypy.translator.llvm.node import LLVMNode, ConstantLLVMNode
from pypy.translator.llvm.opwriter import OpWriter
from pypy.translator.llvm.log import log
+from pypy.translator.llvm.backendopt.removeexcmallocs import remove_exception_mallocs
+from pypy.translator.llvm.backendopt.mergemallocs import merge_mallocs
from pypy.translator.unsimplify import remove_double_links
log = log.funcnode
@@ -38,6 +40,8 @@
self.ref = self.make_ref('%pypy_', value.graph.name)
self.graph = value.graph
self.db.genllvm.exceptionpolicy.transform(self.db.translator, self.graph)
+ #remove_exception_mallocs(self.db.translator, self.graph)
+ #merge_mallocs(self.db.translator, self.graph)
remove_double_links(self.db.translator, self.graph)
def __str__(self):
Modified: pypy/dist/pypy/translator/llvm/genllvm.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/genllvm.py (original)
+++ pypy/dist/pypy/translator/llvm/genllvm.py Tue Sep 27 15:33:10 2005
@@ -253,7 +253,7 @@
a = t.annotate(annotation)
a.simplify()
t.specialize()
- t.backend_optimizations(ssa_form=False)
+ t.backend_optimizations(ssa_form=False, propagate=False, removezerobytemallocs=False)
if view: #note: this is without policy transforms
t.view()
return genllvm(t, **kwds)
Modified: pypy/dist/pypy/translator/llvm/module/extfunction.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/module/extfunction.py (original)
+++ pypy/dist/pypy/translator/llvm/module/extfunction.py Tue Sep 27 15:33:10 2005
@@ -1,6 +1,9 @@
extdeclarations = '''
%last_exception_type = internal global %RPYTHON_EXCEPTION_VTABLE* null
%last_exception_value = internal global %RPYTHON_EXCEPTION* null
+
+%exception_ringbuffer = internal global [8192 x sbyte] zeroinitializer
+%exception_ringbuffer_index = internal global int 0
'''
extfunctions = {} #dependencies, llvm-code
More information about the Pypy-commit
mailing list