[pypy-svn] r25495 - in pypy/dist/pypy: rpython rpython/memory translator/backendopt translator/backendopt/test translator/c
cfbolz at codespeak.net
cfbolz at codespeak.net
Fri Apr 7 15:18:08 CEST 2006
Author: cfbolz
Date: Fri Apr 7 15:18:05 2006
New Revision: 25495
Modified:
pypy/dist/pypy/rpython/memory/gctransform.py
pypy/dist/pypy/rpython/rtyper.py
pypy/dist/pypy/translator/backendopt/all.py
pypy/dist/pypy/translator/backendopt/inline.py
pypy/dist/pypy/translator/backendopt/removenoops.py
pypy/dist/pypy/translator/backendopt/test/test_inline.py
pypy/dist/pypy/translator/backendopt/test/test_propagate.py
pypy/dist/pypy/translator/backendopt/test/test_removenoops.py
pypy/dist/pypy/translator/c/exceptiontransform.py
Log:
(pedronis, cfbolz):
introduced an optimizations remove_duplicate_casts to reduce the size of the
live variable set. For this we needed to make the exception heuristic in
inlining cleverer.
Modified: pypy/dist/pypy/rpython/memory/gctransform.py
==============================================================================
--- pypy/dist/pypy/rpython/memory/gctransform.py (original)
+++ pypy/dist/pypy/rpython/memory/gctransform.py Fri Apr 7 15:18:05 2006
@@ -38,6 +38,8 @@
else:
self.mixlevelannotator = None
self.inline = inline
+ if inline:
+ self.lltype_to_classdef = translator.rtyper.lltype_to_classdef_mapping()
self.graphs_to_inline = {}
def get_lltype_of_exception_value(self):
@@ -87,7 +89,8 @@
from pypy.translator.backendopt import inline
for inline_graph in self.graphs_to_inline:
try:
- inline.inline_function(self.translator, inline_graph, graph)
+ inline.inline_function(self.translator, inline_graph, graph,
+ self.lltype_to_classdef)
except inline.CannotInline:
pass
checkgraph(graph)
Modified: pypy/dist/pypy/rpython/rtyper.py
==============================================================================
--- pypy/dist/pypy/rpython/rtyper.py (original)
+++ pypy/dist/pypy/rpython/rtyper.py Fri Apr 7 15:18:05 2006
@@ -102,6 +102,12 @@
def getexceptiondata(self):
return self.exceptiondata # built at the end of specialize()
+ def lltype_to_classdef_mapping(self):
+ result = {}
+ for (classdef, _), repr in self.instance_reprs.iteritems():
+ result[repr.lowleveltype] = classdef
+ return result
+
def makekey(self, s_obj):
return pair(self.type_system, s_obj).rtyper_makekey(self)
Modified: pypy/dist/pypy/translator/backendopt/all.py
==============================================================================
--- pypy/dist/pypy/translator/backendopt/all.py (original)
+++ pypy/dist/pypy/translator/backendopt/all.py Fri Apr 7 15:18:05 2006
@@ -1,5 +1,5 @@
from pypy.translator.backendopt.raisingop2direct_call import raisingop2direct_call
-from pypy.translator.backendopt.removenoops import remove_same_as, remove_superfluous_keep_alive
+from pypy.translator.backendopt import removenoops
from pypy.translator.backendopt.inline import auto_inlining
from pypy.translator.backendopt.malloc import remove_simple_mallocs
from pypy.translator.backendopt.ssa import SSI_to_SSA
@@ -29,9 +29,10 @@
# remove obvious no-ops
for graph in translator.graphs:
- remove_same_as(graph)
+ removenoops.remove_same_as(graph)
simplify.eliminate_empty_blocks(graph)
simplify.transform_dead_op_vars(graph, translator)
+ removenoops.remove_duplicate_casts(graph, translator)
if PRINT_STATISTICS:
print "after no-op removal:"
@@ -45,7 +46,8 @@
if inline_threshold:
auto_inlining(translator, inline_threshold)
for graph in translator.graphs:
- remove_superfluous_keep_alive(graph)
+ removenoops.remove_superfluous_keep_alive(graph)
+ removenoops.remove_duplicate_casts(graph, translator)
if PRINT_STATISTICS:
print "after inlining:"
@@ -58,7 +60,7 @@
count = remove_simple_mallocs(graph)
if count:
# remove typical leftovers from malloc removal
- remove_same_as(graph)
+ removenoops.remove_same_as(graph)
simplify.eliminate_empty_blocks(graph)
simplify.transform_dead_op_vars(graph, translator)
tot += count
Modified: pypy/dist/pypy/translator/backendopt/inline.py
==============================================================================
--- pypy/dist/pypy/translator/backendopt/inline.py (original)
+++ pypy/dist/pypy/translator/backendopt/inline.py Fri Apr 7 15:18:05 2006
@@ -6,7 +6,7 @@
from pypy.objspace.flow.model import SpaceOperation, c_last_exception
from pypy.objspace.flow.model import traverse, mkentrymap, checkgraph
from pypy.annotation import model as annmodel
-from pypy.rpython.lltypesystem.lltype import Bool, typeOf, Void
+from pypy.rpython.lltypesystem.lltype import Bool, typeOf, Void, Ptr
from pypy.rpython import rmodel
from pypy.tool.algo import sparsemat
from pypy.translator.backendopt.support import log, split_block_with_keepalive, generate_keepalive
@@ -67,25 +67,28 @@
except StopIteration:
return False
-def inline_function(translator, inline_func, graph):
- inliner = Inliner(translator, graph, inline_func)
+def inline_function(translator, inline_func, graph, lltype_to_classdef):
+ inliner = Inliner(translator, graph, inline_func, lltype_to_classdef)
return inliner.inline_all()
+def simple_inline_function(translator, inline_func, graph):
+ inliner = Inliner(translator, graph, inline_func,
+ translator.rtyper.lltype_to_classdef_mapping())
+ return inliner.inline_all()
+
+
def _find_exception_type(block):
#XXX slightly brittle: find the exception type for simple cases
#(e.g. if you do only raise XXXError) by doing pattern matching
- ops = [op for op in block.operations if op.opname != 'keepalive']
- if (len(ops) < 6 or
- ops[-6].opname != "malloc" or ops[-5].opname != "cast_pointer" or
- ops[-4].opname != "setfield" or ops[-3].opname != "cast_pointer" or
- ops[-2].opname != "getfield" or ops[-1].opname != "cast_pointer" or
- len(block.exits) != 1 or block.exits[0].args[0] != ops[-2].result or
- block.exitswitch is not None or
- block.exits[0].args[1] != ops[-1].result or
- not isinstance(ops[-4].args[1], Constant) or
- ops[-4].args[1].value != "typeptr"):
+ currvar = block.exits[0].args[1]
+ for op in block.operations[::-1]:
+ if op.opname in ("same_as", "cast_pointer") and op.result is currvar:
+ currvar = op.args[0]
+ elif op.opname == "malloc" and op.result is currvar:
+ break
+ else:
return None, None
- return ops[-4].args[2].value, block.exits[0]
+ return Ptr(op.args[0].value), block.exits[0]
def does_raise_directly(graph, raise_analyzer):
""" this function checks, whether graph contains operations which can raise
@@ -101,7 +104,8 @@
return False
class BaseInliner(object):
- def __init__(self, translator, graph, inline_guarded_calls=False,
+ def __init__(self, translator, graph, lltype_to_classdef,
+ inline_guarded_calls=False,
inline_guarded_calls_no_matter_what=False, raise_analyzer=None):
self.translator = translator
self.graph = graph
@@ -114,6 +118,7 @@
self.raise_analyzer = raise_analyzer
else:
self.raise_analyzer = None
+ self.lltype_to_classdef = lltype_to_classdef
def inline_all(self):
count = 0
@@ -274,22 +279,27 @@
def rewire_exceptblock_with_guard(self, afterblock, copiedexceptblock):
# this rewiring does not always succeed. in the cases where it doesn't
# there will be generic code inserted
+ from pypy.rpython.lltypesystem import rclass
exc_match = self.translator.rtyper.getexceptiondata().fn_exception_match
for link in self.entrymap[self.graph_to_inline.exceptblock]:
copiedblock = self.copy_block(link.prevblock)
- eclass, copiedlink = _find_exception_type(copiedblock)
+ VALUE, copiedlink = _find_exception_type(copiedblock)
#print copiedblock.operations
- if eclass is None:
+ if VALUE is None or VALUE not in self.lltype_to_classdef:
continue
- etype = copiedlink.args[0]
- evalue = copiedlink.args[1]
+ classdef = self.lltype_to_classdef[VALUE]
+ rtyper = self.translator.rtyper
+ classrepr = rclass.getclassrepr(rtyper, classdef)
+ vtable = classrepr.getruntime()
+ var_etype = copiedlink.args[0]
+ var_evalue = copiedlink.args[1]
for exceptionlink in afterblock.exits[1:]:
- if exc_match(eclass, exceptionlink.llexitcase):
+ if exc_match(vtable, exceptionlink.llexitcase):
passon_vars = self.passon_vars(link.prevblock)
copiedblock.operations += generate_keepalive(passon_vars)
copiedlink.target = exceptionlink.target
linkargs = self.find_args_in_exceptional_case(
- exceptionlink, link.prevblock, etype, evalue, afterblock, passon_vars)
+ exceptionlink, link.prevblock, var_etype, var_evalue, afterblock, passon_vars)
copiedlink.args = linkargs
break
@@ -387,9 +397,9 @@
class Inliner(BaseInliner):
- def __init__(self, translator, graph, inline_func, inline_guarded_calls=False,
+ def __init__(self, translator, graph, inline_func, lltype_to_classdef, inline_guarded_calls=False,
inline_guarded_calls_no_matter_what=False, raise_analyzer=None):
- BaseInliner.__init__(self, translator, graph,
+ BaseInliner.__init__(self, translator, graph, lltype_to_classdef,
inline_guarded_calls,
inline_guarded_calls_no_matter_what,
raise_analyzer)
@@ -403,21 +413,10 @@
self.block_to_index.setdefault(block, {})[i] = g
class OneShotInliner(BaseInliner):
- def __init__(self, translator, graph, inline_guarded_calls=False,
- inline_guarded_calls_no_matter_what=False, raise_analyzer=None):
- BaseInliner.__init__(self, translator, graph,
- inline_guarded_calls,
- inline_guarded_calls_no_matter_what,
- raise_analyzer)
-
def search_for_calls(self, block):
pass
-def _inline_function(translator, graph, block, index_operation):
- inline_func = block.operations[index_operation].args[0].value._obj._callable
- inliner = Inliner(translator, graph, inline_func)
-
# ____________________________________________________________
#
# Automatic inlining
@@ -509,6 +508,7 @@
fiboheap = [(0.0, graph) for graph in callers]
valid_weight = {}
couldnt_inline = {}
+ lltype_to_classdef = translator.rtyper.lltype_to_classdef_mapping()
while fiboheap:
weight, graph = fiboheap[0]
@@ -529,7 +529,8 @@
continue
sys.stdout.flush()
try:
- res = bool(inline_function(translator, graph, parentgraph))
+ res = bool(inline_function(translator, graph, parentgraph,
+ lltype_to_classdef))
except CannotInline:
couldnt_inline[graph] = True
res = CannotInline
Modified: pypy/dist/pypy/translator/backendopt/removenoops.py
==============================================================================
--- pypy/dist/pypy/translator/backendopt/removenoops.py (original)
+++ pypy/dist/pypy/translator/backendopt/removenoops.py Fri Apr 7 15:18:05 2006
@@ -1,6 +1,7 @@
from pypy.objspace.flow.model import Block, Variable, Constant
from pypy.objspace.flow.model import traverse
from pypy.rpython.lltypesystem.lltype import Void
+from pypy.translator.backendopt.support import log
from pypy.translator import simplify
from pypy import conftest
@@ -114,7 +115,8 @@
else:
for arg in op.args:
used[arg] = True
- print "removed %s cast_pointers in %s" % (num_removed, graph.name)
+ log.removecasts(
+ "removed %s cast_pointers in %s" % (num_removed, graph.name))
return num_removed
def remove_superfluous_keep_alive(graph):
Modified: pypy/dist/pypy/translator/backendopt/test/test_inline.py
==============================================================================
--- pypy/dist/pypy/translator/backendopt/test/test_inline.py (original)
+++ pypy/dist/pypy/translator/backendopt/test/test_inline.py Fri Apr 7 15:18:05 2006
@@ -4,7 +4,7 @@
from pypy.objspace.flow.model import traverse, Block, Link, Variable, Constant
from pypy.objspace.flow.model import last_exception, checkgraph
from pypy.translator.backendopt import canraise
-from pypy.translator.backendopt.inline import inline_function, CannotInline
+from pypy.translator.backendopt.inline import simple_inline_function, CannotInline
from pypy.translator.backendopt.inline import auto_inlining, Inliner
from pypy.translator.backendopt.inline import collect_called_graphs
from pypy.translator.backendopt.inline import measure_median_execution_cost
@@ -56,10 +56,11 @@
raise_analyzer = canraise.RaiseAnalyzer(t)
else:
raise_analyzer = None
- inliner = Inliner(t, graphof(t, in_func), func, inline_guarded_calls,
+ inliner = Inliner(t, graphof(t, in_func), func,
+ t.rtyper.lltype_to_classdef_mapping(),
+ inline_guarded_calls,
raise_analyzer=raise_analyzer)
inliner.inline_all()
-# inline_function(t, func, graphof(t, in_func))
if option.view:
t.view()
sanity_check(t)
@@ -282,7 +283,7 @@
break
else:
assert 0, "cannot find ll_rangenext_*() function"
- inline_function(t, graph, graphof(t, f))
+ simple_inline_function(t, graph, graphof(t, f))
sanity_check(t)
interp = LLInterpreter(t.rtyper)
result = interp.eval_graph(graphof(t, f), [10])
Modified: pypy/dist/pypy/translator/backendopt/test/test_propagate.py
==============================================================================
--- pypy/dist/pypy/translator/backendopt/test/test_propagate.py (original)
+++ pypy/dist/pypy/translator/backendopt/test/test_propagate.py Fri Apr 7 15:18:05 2006
@@ -6,12 +6,13 @@
from pypy.rpython.memory.test.test_gctransform import getops
from pypy import conftest
-def get_graph(fn, signature, inline_threshold=True):
+def get_graph(fn, signature, inline_threshold=True, all_opts=True):
t = TranslationContext()
t.buildannotator().build_types(fn, signature)
t.buildrtyper().specialize()
- backend_optimizations(t, inline_threshold=inline_threshold,
- ssa_form=False, propagate=False)
+ if all_opts:
+ backend_optimizations(t, inline_threshold=inline_threshold,
+ ssa_form=False, propagate=False)
graph = graphof(t, fn)
if conftest.option.view:
t.view()
Modified: pypy/dist/pypy/translator/backendopt/test/test_removenoops.py
==============================================================================
--- pypy/dist/pypy/translator/backendopt/test/test_removenoops.py (original)
+++ pypy/dist/pypy/translator/backendopt/test/test_removenoops.py Fri Apr 7 15:18:05 2006
@@ -1,6 +1,6 @@
from pypy.translator.backendopt.removenoops import remove_void, remove_same_as, \
remove_unaryops, remove_duplicate_casts, remove_superfluous_keep_alive
-from pypy.translator.backendopt.inline import inline_function
+from pypy.translator.backendopt.inline import simple_inline_function
from pypy.translator.backendopt.test.test_propagate import getops, get_graph, check_graph
from pypy.translator.translator import TranslationContext, graphof
from pypy.translator.test.snippet import simple_method
@@ -60,7 +60,7 @@
t.buildrtyper().specialize()
# now we make the 'if True' appear
f_graph = graphof(t, f)
- inline_function(t, nothing, f_graph)
+ simple_inline_function(t, nothing, f_graph)
# here, the graph looks like v21=same_as(True); exitswitch: v21
remove_same_as(f_graph)
t.checkgraphs()
@@ -127,7 +127,7 @@
c = B(x, x + 1, x + 2)
return a.x + a.y + b.x + b.y + b.z + c.getsum()
assert f(10, True) == 75
- graph, t = get_graph(f, [int, bool], 1)
+ graph, t = get_graph(f, [int, bool], 1, False)
num_cast_pointer = len(getops(graph)['cast_pointer'])
changed = remove_duplicate_casts(graph, t)
assert changed
Modified: pypy/dist/pypy/translator/c/exceptiontransform.py
==============================================================================
--- pypy/dist/pypy/translator/c/exceptiontransform.py (original)
+++ pypy/dist/pypy/translator/c/exceptiontransform.py Fri Apr 7 15:18:05 2006
@@ -113,6 +113,8 @@
lltype.Ptr(RPYEXC_RAISE))
mixlevelannotator.finish()
+
+ self.lltype_to_classdef = translator.rtyper.lltype_to_classdef_mapping()
def transform_completely(self):
for graph in self.translator.graphs:
@@ -189,10 +191,10 @@
#non-exception case
block.exits[0].exitcase = block.exits[0].llexitcase = None
# use the dangerous second True flag :-)
- inliner = inline.OneShotInliner(self.translator, graph,
- inline_guarded_calls=True,
- inline_guarded_calls_no_matter_what=True,
- raise_analyzer=self.raise_analyzer)
+ inliner = inline.OneShotInliner(
+ self.translator, graph, self.lltype_to_classdef,
+ inline_guarded_calls=True, inline_guarded_calls_no_matter_what=True,
+ raise_analyzer=self.raise_analyzer)
inliner.inline_once(block, len(block.operations)-1)
#block.exits[0].exitcase = block.exits[0].llexitcase = False
More information about the Pypy-commit
mailing list