[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