[pypy-svn] r32685 - in pypy/branch/jit-promotion/pypy: jit/codegen/llgraph jit/timeshifter jit/timeshifter/test rpython

arigo at codespeak.net arigo at codespeak.net
Thu Sep 28 00:35:36 CEST 2006


Author: arigo
Date: Thu Sep 28 00:35:30 2006
New Revision: 32685

Modified:
   pypy/branch/jit-promotion/pypy/jit/codegen/llgraph/llimpl.py
   pypy/branch/jit-promotion/pypy/jit/codegen/llgraph/rgenop.py
   pypy/branch/jit-promotion/pypy/jit/timeshifter/rtimeshift.py
   pypy/branch/jit-promotion/pypy/jit/timeshifter/rtyper.py
   pypy/branch/jit-promotion/pypy/jit/timeshifter/test/test_promotion.py
   pypy/branch/jit-promotion/pypy/jit/timeshifter/test/test_timeshift.py
   pypy/branch/jit-promotion/pypy/jit/timeshifter/transform.py
   pypy/branch/jit-promotion/pypy/rpython/annlowlevel.py
   pypy/branch/jit-promotion/pypy/rpython/llinterp.py
Log:
(pedronis, arigo)

Next intermediate check-in.  The first real promotion tests pass!
Fix the other tests tomorrow... good night.


Modified: pypy/branch/jit-promotion/pypy/jit/codegen/llgraph/llimpl.py
==============================================================================
--- pypy/branch/jit-promotion/pypy/jit/codegen/llgraph/llimpl.py	(original)
+++ pypy/branch/jit-promotion/pypy/jit/codegen/llgraph/llimpl.py	Thu Sep 28 00:35:30 2006
@@ -41,6 +41,11 @@
     block.inputargs.append(v)
     return to_opaque_object(v)
 
+def getinputarg(blockcontainer, i):
+    block = from_opaque_object(blockcontainer.obj)
+    v = block.inputargs[i]
+    return to_opaque_object(v)
+
 def _inputvars(vars):
     newvars = []
     if not isinstance(vars, list):
@@ -218,7 +223,7 @@
     block = from_opaque_object(blockcontainer.obj)
     exitcase = from_opaque_object(exitcase)
     assert isinstance(exitcase, flowmodel.Constant)
-    assert isinstance(block.exitswitch, Variable)
+    assert isinstance(block.exitswitch, flowmodel.Variable)
     case_link = flowmodel.Link([], None)
     case_link.exitcase = exitcase.value
     case_link.llexitcase = exitcase.value
@@ -258,10 +263,15 @@
         raise TypeError
 
 def closelink(link, vars, targetblockcontainer):
-    link = from_opaque_object(link)
-    targetblock = from_opaque_object(targetblockcontainer.obj)
-    vars = _inputvars(vars)
-    _closelink(link, vars, targetblock)
+    try:
+        link = from_opaque_object(link)
+        targetblock = from_opaque_object(targetblockcontainer.obj)
+        vars = _inputvars(vars)
+        _closelink(link, vars, targetblock)
+    except Exception, e:
+        import sys; tb = sys.exc_info()[2]
+        import pdb; pdb.post_mortem(tb)
+        raise
 
 ##def closereturnlink(link, returnvar):
 ##    returnvar = from_opaque_object(returnvar)
@@ -355,6 +365,17 @@
     graph = buildgraph(blockcontainer, returncontainer, FUNCTYPE)
     return testgengraph(graph, args, viewbefore, executor)
 
+def show_incremental_progress(someblockcontainer):
+    from pypy import conftest
+    if conftest.option.view:
+        try:
+            someblock = from_opaque_object(someblockcontainer.obj)
+            someblock.show()
+        except Exception, e:
+            import sys; tb = sys.exc_info()[2]
+            import pdb; pdb.post_mortem(tb)
+            raise
+
 # ____________________________________________________________
 # RTyping of the above functions
 
@@ -419,6 +440,7 @@
 
 setannotation(initblock, None)
 setannotation(geninputarg, s_ConstOrVar)
+setannotation(getinputarg, s_ConstOrVar)
 setannotation(genop, s_ConstOrVar)
 setannotation(gencallableconst, s_ConstOrVar)
 setannotation(genconst, s_ConstOrVar)
@@ -439,3 +461,5 @@
 setannotation(constFieldName, s_ConstOrVar, specialize_as_constant=True)
 setannotation(constTYPE,      s_ConstOrVar, specialize_as_constant=True)
 #setannotation(placeholder,    s_ConstOrVar, specialize_as_constant=True)
+
+setannotation(show_incremental_progress, None)

Modified: pypy/branch/jit-promotion/pypy/jit/codegen/llgraph/rgenop.py
==============================================================================
--- pypy/branch/jit-promotion/pypy/jit/codegen/llgraph/rgenop.py	(original)
+++ pypy/branch/jit-promotion/pypy/jit/codegen/llgraph/rgenop.py	Thu Sep 28 00:35:30 2006
@@ -163,6 +163,9 @@
         self.lnk = l_default
         return flexswitch
 
+    def show_incremental_progress(self):
+        llimpl.show_incremental_progress(self.g)
+
 
 class RGenOp(AbstractRGenOp):
     gv_Void = gv_Void
@@ -230,6 +233,10 @@
         args_gv = builder._newblock(kinds)
         return builder, args_gv
 
+    def stop_replay(self, endblock, kinds):
+        return [LLVar(llimpl.getinputarg(endblock.b, i))
+                for i in range(len(kinds))]
+
     # not RPython, just for debugging.  Specific to llgraph.
     @staticmethod
     def reveal(gv):

Modified: pypy/branch/jit-promotion/pypy/jit/timeshifter/rtimeshift.py
==============================================================================
--- pypy/branch/jit-promotion/pypy/jit/timeshifter/rtimeshift.py	(original)
+++ pypy/branch/jit-promotion/pypy/jit/timeshifter/rtimeshift.py	Thu Sep 28 00:35:30 2006
@@ -241,8 +241,15 @@
 
 def split(jitstate, switchredbox, resumepoint, *greens_gv):
     exitgvar = switchredbox.getgenvar(jitstate.curbuilder)
-    later_builder = jitstate.curbuilder.jump_if_false(exitgvar)
-    jitstate.split(later_builder, resumepoint, list(greens_gv))
+    if exitgvar.is_const:
+        return exitgvar.revealconst(lltype.Bool)
+    else:
+        if jitstate.resuming is None:
+            later_builder = jitstate.curbuilder.jump_if_false(exitgvar)
+            jitstate.split(later_builder, resumepoint, list(greens_gv))
+            return True
+        else:
+            return jitstate.resuming.path.pop()
 
 def collect_split(jitstate_chain, resumepoint, *greens_gv):
     greens_gv = list(greens_gv)
@@ -323,9 +330,10 @@
         self.path = path
 
 class PromotionPoint(object):
-    def __init__(self, flexswitch, promotion_path):
+    def __init__(self, flexswitch, switchblock, promotion_path):
         assert promotion_path is not None
         self.flexswitch = flexswitch
+        self.switchblock = switchblock
         self.promotion_path = promotion_path
 
 class AbstractPromotionPath(object):
@@ -355,6 +363,7 @@
         jitstate.resuming = resuminginfo
         assert jitstate.frame.backframe is None
         self.global_resumer(jitstate)
+        builder.show_incremental_progress()
 
 class PromotionPathNode(AbstractPromotionPath):
     def __init__(self, next):
@@ -379,7 +388,8 @@
         resuminginfo = ResumingInfo(promotion_point, gv_value, path)
         root.continue_compilation(resuminginfo)
     except Exception, e:
-        llop.debug_fatalerror(lltype.Void, "compilation-time error", e)
+        lloperation.llop.debug_fatalerror(lltype.Void,
+                                          "compilation-time error", e)
 
 class PromotionDesc:
     __metatype__ = cachedtype
@@ -401,8 +411,9 @@
         return True
 
 def ll_promote(jitstate, box, promotiondesc):
-    if box.is_constant():
-        save_greens(jitstate, box.genvar)
+    builder = jitstate.curbuilder
+    gv_switchvar = box.getgenvar(builder)
+    if gv_switchvar.is_const:
         return False
     else:
         incoming = []
@@ -411,16 +422,18 @@
         switchblock = enter_next_block(jitstate, incoming)
 
         if jitstate.resuming is None:
-            builder = jitstate.curbuilder
-            flexswitch = builder.flexswitch(box.getgenvar(builder))
+            gv_switchvar = box.genvar
+            flexswitch = builder.flexswitch(gv_switchvar)
             # default case of the switch:
             enter_block(jitstate)
-            pm = PromotionPoint(flexswitch, jitstate.promotion_path)
+            pm = PromotionPoint(flexswitch, switchblock,
+                                jitstate.promotion_path)
             ll_pm = cast_instance_to_base_ptr(pm)
             gv_pm = builder.rgenop.genconst(ll_pm)
+            gv_switchvar = box.genvar
             builder.genop_call(promotiondesc.sigtoken,
                                promotiondesc.gv_continue_compilation,
-                               [gv_pm, box.getgenvar(builder)])
+                               [gv_pm, gv_switchvar])
             linkargs = []
             for box in incoming:
                 linkargs.append(box.getgenvar(builder))
@@ -431,13 +444,20 @@
             resuming = jitstate.resuming
             assert len(resuming.path) == 0
             pm = resuming.promotion_point
+
+            kinds = [box.kind for box in incoming]
+            vars_gv = jitstate.curbuilder.rgenop.stop_replay(pm.switchblock,
+                                                             kinds)
+            for i in range(len(incoming)):
+                incoming[i].genvar = vars_gv[i]
+            box.genvar = resuming.gv_value
+
             newbuilder = pm.flexswitch.add_case(resuming.gv_value)
 
             jitstate.resuming = None
             jitstate.promotion_path = pm.promotion_path
             jitstate.curbuilder = newbuilder
             enter_block(jitstate)
-            save_greens(jitstate, resuming.gv_value)
             return False
 
 # ____________________________________________________________

Modified: pypy/branch/jit-promotion/pypy/jit/timeshifter/rtyper.py
==============================================================================
--- pypy/branch/jit-promotion/pypy/jit/timeshifter/rtyper.py	(original)
+++ pypy/branch/jit-promotion/pypy/jit/timeshifter/rtyper.py	Thu Sep 28 00:35:30 2006
@@ -710,8 +710,9 @@
         args_s += [self.s_ConstOrVar] * len(greens_v)
         args_v = [v_jitstate, v_switch, c_resumepoint]
         args_v += greens_v
-        hop.llops.genmixlevelhelpercall(rtimeshift.split, args_s, args_v,
-                                        annmodel.s_None)
+        return hop.llops.genmixlevelhelpercall(rtimeshift.split,
+                                               args_s, args_v,
+                                               annmodel.SomeBool())
 
     def translate_op_collect_split(self, hop):
         GREENS = [v.concretetype for v in hop.args_v[1:]]

Modified: pypy/branch/jit-promotion/pypy/jit/timeshifter/test/test_promotion.py
==============================================================================
--- pypy/branch/jit-promotion/pypy/jit/timeshifter/test/test_promotion.py	(original)
+++ pypy/branch/jit-promotion/pypy/jit/timeshifter/test/test_promotion.py	Thu Sep 28 00:35:30 2006
@@ -1,6 +1,7 @@
 import py
 from pypy.rpython.lltypesystem import lltype
 from pypy.jit.timeshifter.test.test_timeshift import TimeshiftingTests
+from pypy.jit.timeshifter.test.test_timeshift import P_NOVIRTUAL
 from pypy.rpython.objectmodel import hint
 
 
@@ -24,3 +25,19 @@
         res = self.timeshift(ll_function, [20], [])
         assert res == 42
         self.check_insns(int_add=0, int_mul=0)
+
+    def test_many_promotions(self):
+        def ll_two(k):
+            return k*k
+        def ll_function(n, total):
+            while n > 0:
+                k = hint(n, promote=True)
+                k = ll_two(k)
+                total += hint(k, variable=True)
+                n -= 1
+            return total
+        ll_function._global_merge_points_ = True
+
+        res = self.timeshift(ll_function, [10, 0], [], policy=P_NOVIRTUAL)
+        assert res == ll_function(10, 0)
+        self.check_insns(int_add=10, int_mul=0)

Modified: pypy/branch/jit-promotion/pypy/jit/timeshifter/test/test_timeshift.py
==============================================================================
--- pypy/branch/jit-promotion/pypy/jit/timeshifter/test/test_timeshift.py	(original)
+++ pypy/branch/jit-promotion/pypy/jit/timeshifter/test/test_timeshift.py	Thu Sep 28 00:35:30 2006
@@ -271,9 +271,10 @@
         # now try to run the residual graph generated by the builder
         residual_graph = ll_generated._obj.graph
         residual_graph.exceptiontransformed = self.hrtyper.exc_data_ptr
+        self.ll_generated = ll_generated
+        self.residual_graph = residual_graph
         if conftest.option.view:
             residual_graph.show()
-        self.insns = summary(residual_graph)
 
         if 'check_raises' not in kwds:
             res = llinterp.eval_graph(residual_graph, residualargs)
@@ -313,6 +314,7 @@
         return self.timeshift(ll_function, values, opt_consts, *args, **kwds)
 
     def check_insns(self, expected=None, **counts):
+        self.insns = summary(self.residual_graph)
         if expected is not None:
             assert self.insns == expected
         for opname, count in counts.items():

Modified: pypy/branch/jit-promotion/pypy/jit/timeshifter/transform.py
==============================================================================
--- pypy/branch/jit-promotion/pypy/jit/timeshifter/transform.py	(original)
+++ pypy/branch/jit-promotion/pypy/jit/timeshifter/transform.py	Thu Sep 28 00:35:30 2006
@@ -192,6 +192,7 @@
                     self.insert_split_handling(block)
 
     def insert_split_handling(self, block):
+        # lots of clever in-line logic commented out
         v_redswitch = block.exitswitch
         link_f, link_t = block.exits
         if link_f.exitcase:
@@ -199,35 +200,42 @@
         assert link_f.exitcase is False
         assert link_t.exitcase is True
 
-        constant_block = Block([])
-        nonconstant_block = Block([])
+##        constant_block = Block([])
+##        nonconstant_block = Block([])
 
-        v_flag = self.genop(block, 'is_constant', [v_redswitch],
-                            resulttype = lltype.Bool)
-        self.genswitch(block, v_flag, true  = constant_block,
-                                      false = nonconstant_block)
-
-        v_greenswitch = self.genop(constant_block, 'revealconst',
-                                   [v_redswitch],
-                                   resulttype = lltype.Bool)
-        constant_block.exitswitch = v_greenswitch
-        constant_block.closeblock(link_f, link_t)
+##        v_flag = self.genop(block, 'is_constant', [v_redswitch],
+##                            resulttype = lltype.Bool)
+##        self.genswitch(block, v_flag, true  = constant_block,
+##                                      false = nonconstant_block)
+
+##        v_greenswitch = self.genop(constant_block, 'revealconst',
+##                                   [v_redswitch],
+##                                   resulttype = lltype.Bool)
+##        constant_block.exitswitch = v_greenswitch
+##        constant_block.closeblock(link_f, link_t)
 
         reds, greens = self.sort_by_color(link_f.args, link_f.target.inputargs)
-        self.genop(nonconstant_block, 'save_locals', reds)
+        self.genop(block, 'save_locals', reds)
         resumepoint = self.get_resume_point(link_f.target)
         c_resumepoint = inputconst(lltype.Signed, resumepoint)
-        self.genop(nonconstant_block, 'split',
-                   [v_redswitch, c_resumepoint] + greens)
+        v_flag = self.genop(block, 'split',
+                            [v_redswitch, c_resumepoint] + greens,
+                            resulttype = lltype.Bool)
+
+        block.exitswitch = v_flag
+        true_block = Block([])
+        true_link  = Link([], true_block)
+        true_link.exitcase   = True
+        true_link.llexitcase = True
+        block.recloseblock(link_f, true_link)
 
         reds, greens = self.sort_by_color(link_t.args)
-        self.genop(nonconstant_block, 'save_locals', reds)
-        self.genop(nonconstant_block, 'enter_block', [])
-        nonconstant_block.closeblock(Link(link_t.args, link_t.target))
-
-        SSA_to_SSI({block            : True,    # reachable from outside
-                    constant_block   : False,
-                    nonconstant_block: False}, self.hannotator)
+        self.genop(true_block, 'save_locals', reds)
+        self.genop(true_block, 'enter_block', [])
+        true_block.closeblock(Link(link_t.args, link_t.target))
+
+        SSA_to_SSI({block     : True,    # reachable from outside
+                    true_block: False}, self.hannotator)
 
     def get_resume_point_link(self, block):
         try:
@@ -565,8 +573,8 @@
 
     def handle_promote_hint(self, block, i):
         op = block.operations[i]
-        c_zero = inputconst(lltype.Signed, 0)
-        newop = SpaceOperation('restore_green', [c_zero], op.result)
+        v_promote = op.args[0]
+        newop = SpaceOperation('revealconst', [v_promote], op.result)
         block.operations[i] = newop
 
         link = support.split_block_with_keepalive(block, i,
@@ -574,9 +582,6 @@
         nextblock = link.target
 
         reds, greens = self.sort_by_color(link.args)
-        v_promote = op.args[0]
-        if v_promote not in reds:
-            reds.append(v_promote)
         self.genop(block, 'save_locals', reds)
         v_finished_flag = self.genop(block, 'promote', [v_promote],
                                      resulttype = lltype.Bool)

Modified: pypy/branch/jit-promotion/pypy/rpython/annlowlevel.py
==============================================================================
--- pypy/branch/jit-promotion/pypy/rpython/annlowlevel.py	(original)
+++ pypy/branch/jit-promotion/pypy/rpython/annlowlevel.py	Thu Sep 28 00:35:30 2006
@@ -347,6 +347,7 @@
         return annmodel.SomePtr(F)
 
     def specialize_call(self, hop):
+        hop.exception_cannot_occur()
         return hop.args_r[1].get_unique_llfn()
 
 # ____________________________________________________________
@@ -372,6 +373,7 @@
     def specialize_call(self, hop):
         v_arg = hop.inputarg(hop.args_r[1], arg=1)
         assert isinstance(v_arg.concretetype, lltype.Ptr)
+        hop.exception_cannot_occur()
         return hop.genop('cast_pointer', [v_arg],
                          resulttype = hop.r_result.lowleveltype)
 
@@ -391,6 +393,7 @@
     def specialize_call(self, hop):
         v_arg = hop.inputarg(hop.args_r[1], arg=1)
         assert isinstance(v_arg.concretetype, lltype.Ptr)
+        hop.exception_cannot_occur()
         return hop.genop('cast_pointer', [v_arg],
                          resulttype = hop.r_result.lowleveltype)
 
@@ -409,11 +412,7 @@
 ##        s_Instance, r_Instance = pol.annhelper.s_r_instanceof(s_Class.const)
 ##        return annmodel.SomePtr(r_Instance.lowleveltype)
 
-##    def specialize_call(self, hop):
-##        v_arg = hop.inputarg(hop.args_r[1], arg=1)
-##        assert isinstance(v_arg.concretetype, lltype.Ptr)
-##        return hop.genop('cast_pointer', [v_arg],
-##                         resulttype = hop.r_result.lowleveltype)
+##    ...
 
 # ____________________________________________________________
 

Modified: pypy/branch/jit-promotion/pypy/rpython/llinterp.py
==============================================================================
--- pypy/branch/jit-promotion/pypy/rpython/llinterp.py	(original)
+++ pypy/branch/jit-promotion/pypy/rpython/llinterp.py	Thu Sep 28 00:35:30 2006
@@ -27,6 +27,10 @@
             extra = ''
         return '<LLException %r%s>' % (type_name(etype), extra)
 
+class LLFatalError(Exception):
+    def __str__(self):
+        return ': '.join([str(x) for x in self.args])
+
 def type_name(etype):
     if isinstance(lltype.typeOf(etype), lltype.Ptr):
         return ''.join(etype.name).rstrip('\x00')
@@ -442,6 +446,14 @@
         # do nothing, this is useful in compiled code
         pass
 
+    def op_debug_fatalerror(self, ll_msg, ll_exc=None):
+        msg = ''.join(ll_msg.chars)
+        if ll_exc is None:
+            raise LLFatalError(msg)
+        else:
+            ll_exc_type = lltype.cast_pointer(rclass.OBJECTPTR, ll_exc).typeptr
+            raise LLFatalError(msg, LLException(ll_exc_type, ll_exc))
+
     def op_keepalive(self, value):
         pass
 
@@ -903,22 +915,33 @@
 
     HEADER = """<html><head>
         <script language=javascript type='text/javascript'>
-        function togglestate(name) {
-          item = document.getElementById(name)
+        function togglestate(n) {
+          var item = document.getElementById('div'+n)
           if (item.style.display == 'none')
             item.style.display = 'block';
           else
             item.style.display = 'none';
         }
+
+        function toggleall(lst) {
+          for (var i = 0; i<lst.length; i++) {
+            togglestate(lst[i]);
+          }
+        }
         </script>
         </head>
 
         <body><pre>
     """
 
-    FOOTER = """</pre></body></html>"""
+    FOOTER = """</pre>
+        <script language=javascript type='text/javascript'>
+        toggleall(%r);
+        </script>
+
+    </body></html>"""
 
-    ENTER = ('''\n\t<a href="javascript:togglestate('div%d')">%s</a>'''
+    ENTER = ('''\n\t<a href="javascript:togglestate(%d)">%s</a>'''
              '''\n<div id="div%d" style="display: %s">\t''')
     LEAVE = '''\n</div>\t'''
 
@@ -951,17 +974,22 @@
 
         self.count = 0
         self.indentation = ''
+        self.depth = 0
+        self.latest_call_chain = []
 
     def stop(self):
         # end of a dump file
         if self.file:
-            print >> self.file, self.FOOTER
+            print >> self.file, self.FOOTER % (self.latest_call_chain[1:])
             self.file.close()
             self.file = None
 
     def enter(self, graph):
         # enter evaluation of a graph
         if self.file:
+            del self.latest_call_chain[self.depth:]
+            self.depth += 1
+            self.latest_call_chain.append(self.count)
             s = self.htmlquote(str(graph))
             i = s.rfind(')')
             s = s[:i+1] + '<b>' + s[i+1:] + '</b>'
@@ -979,6 +1007,7 @@
         if self.file:
             self.indentation = self.indentation[:-4]
             self.file.write(self.LEAVE.replace('\t', self.indentation))
+            self.depth -= 1
 
     def dump(self, text, bold=False):
         if self.file:



More information about the Pypy-commit mailing list