[pypy-svn] r23187 - in pypy/dist/pypy: jit jit/test rpython

arigo at codespeak.net arigo at codespeak.net
Thu Feb 9 21:41:37 CET 2006


Author: arigo
Date: Thu Feb  9 21:41:36 2006
New Revision: 23187

Added:
   pypy/dist/pypy/jit/hintrtyper.py
      - copied, changed from r23120, pypy/dist/pypy/jit/hintrtyper.py
Modified:
   pypy/dist/pypy/jit/hinttimeshift.py
   pypy/dist/pypy/jit/rtimeshift.py
   pypy/dist/pypy/jit/test/test_hint_timeshift.py
   pypy/dist/pypy/rpython/rtyper.py
Log:
(arigo, pedronis)

very much work-in-progress (see XXXs)

refactor Hint Time Shifter to reuse typer logic, creating a special
HintRTyper.

so we can reuse the its conversion logic etc.

Bad news:
- using laziness for now to deal with rgenop interface problems
  (you need a block to much everything)

- the typer conversion logic for constants really assume that
  they can be simply translated into a global static object.
  It's not cleat that this makes sense for the constants
  in time shifted graphs, they may need to create fresh boxes
  for each execution, otherwise there are potential races etc...




Modified: pypy/dist/pypy/jit/hinttimeshift.py
==============================================================================
--- pypy/dist/pypy/jit/hinttimeshift.py	(original)
+++ pypy/dist/pypy/jit/hinttimeshift.py	Thu Feb  9 21:41:36 2006
@@ -1,31 +1,17 @@
-from pypy.jit import hintmodel
 from pypy.rpython.lltypesystem import lltype
-from pypy.rpython.rmodel import inputconst
-from pypy.rpython.rtyper import LowLevelOpList
-from pypy.rpython.rstr import string_repr
-from pypy.rpython import rgenop
 from pypy.objspace.flow import model as flowmodel
-from pypy.annotation import model as annmodel
 from pypy.jit.rtimeshift import STATE_PTR, REDBOX_PTR 
 from pypy.jit import rtimeshift
+from pypy.jit.hintrtyper import HintRTyper, s_JITState, originalconcretetype
 
 # ___________________________________________________________
 
-def ll_fixed_items(l):
-    return l
-
-VARLIST = lltype.Ptr(lltype.GcArray(rgenop.CONSTORVAR,
-                                    adtmeths = {
-                                        "ll_items": ll_fixed_items,
-                                    }))
-
 class HintTimeshift(object):
     
     def __init__(self, hannotator, rtyper):
         self.hannotator = hannotator
         self.rtyper = rtyper
-        self.varcolor = {}
-        self.varconcretetype = {}
+        self.hrtyper = HintRTyper(hannotator, self)
 
     def timeshift(self):
         for graph in self.hannotator.translator.graphs:
@@ -34,101 +20,25 @@
         self.rtyper.specialize_more_blocks()
 
     def timeshift_graph(self, graph):
-        for block in graph.iterblocks():
+        originalblocks = list(graph.iterblocks())
+        for block in originalblocks:
+            self.pre_process_block(block)
+        for block in originalblocks:
             self.timeshift_block(block)
 
+    def pre_process_block(self, block):
+        # pass 'jitstate' as an extra argument around the whole graph
+        if block.operations != ():
+            v_jitstate = flowmodel.Variable('jitstate')
+            self.hannotator.bindings[v_jitstate] = s_JITState
+            block.inputargs.insert(0, v_jitstate)
+            for link in block.exits:
+                # not for links going to the return/except block
+                if link.target.operations != ():
+                    link.args.insert(0, v_jitstate)
+
     def timeshift_block(self, block):
-        for inputarg in block.inputargs:
-            self.introduce_var(inputarg)
-        if not block.exits:
-            return    # nothing else to do
-        self.jitstate = flowmodel.Variable('jitstate')
-        self.jitstate.concretetype = STATE_PTR
-
-        # look for "red" operations
-        newops = LowLevelOpList(self.rtyper)
-        for op in block.operations:
-            green = True
-            for arg in op.args:
-                if self.varcolor.get(arg, "green") != "green":
-                    green = False
-            self.introduce_var(op.result)
-            if green and self.varcolor[op.result] == "green":
-                # XXX check for side effect ops
-                newops.append(op)
-                continue
-            print "RED", op
-            self.timeshift_op(op, newops)
-            
-        block.operations[:] = newops
+        self.hrtyper.specialize_block(block)
 
-        # pass 'jitstate' as an extra argument around the whole graph
-        block.inputargs.insert(0, self.jitstate)
-        for link in block.exits:
-            if link.target.exits:  # not if going to the return/except block
-                link.args.insert(0, self.jitstate)
-
-    def timeshift_op(self, op, newops):
-        handler = getattr(self, 'tshift_' + op.opname, self.default_tshift)
-        v_res = handler(op, newops)
-        if v_res is not None:
-            assert v_res.concretetype == op.result.concretetype
-            op1 = flowmodel.SpaceOperation('same_as', [v_res], op.result)
-            newops.append(op1)
-
-    def introduce_var(self, v):
-        self.varconcretetype[v] = v.concretetype
-        if self.is_green(v):
-            color = "green"
-        else:
-            color = "red"
-            v.concretetype = REDBOX_PTR
-        self.varcolor[v] = color
-
-    def is_green(self, var):
-        hs_var = self.hannotator.binding(var)
-        if hs_var == annmodel.s_ImpossibleValue:
-            return True
-        elif isinstance(hs_var, hintmodel.SomeLLAbstractConstant):
-            return hs_var.eager_concrete or hs_var.is_fixed()
-        else:
-            return False
-
-    def get_genop_var(self, var, llops):
-        color = self.varcolor.get(var, "green")
-        if color == "red":
-            return llops.gendirectcall(rtimeshift.ll_gvar_from_redbox,
-                                       self.jitstate, var)
-        elif color == "green":
-            return llops.gendirectcall(rtimeshift.ll_gvar_from_constant,
-                                       self.jitstate, var)
-        else:
-            raise NotImplementedError(color)
-
-    # ____________________________________________________________
-
-    def default_tshift(self, op, llops):
-        # by default, a red operation converts all its arguments to
-        # genop variables, and emits a call to a helper that will generate
-        # the same operation at run-time
-        # XXX constant propagate if possible        
-        v_args = llops.genop('malloc_varsize',
-                             [inputconst(lltype.Void, VARLIST.TO),
-                              inputconst(lltype.Signed, len(op.args))],
-                             resulttype = VARLIST)
-        for i, arg in enumerate(op.args):
-            v_gvar = self.get_genop_var(arg, llops)
-            llops.genop('setarrayitem', [v_args,
-                                         inputconst(lltype.Signed, i),
-                                         v_gvar])
-        v_restype = inputconst(lltype.Void, self.varconcretetype[op.result])
-        v_res = llops.gendirectcall(rtimeshift.ll_generate_operation,
-                                    self.jitstate, opname2vstr(op.opname),
-                                    v_args, v_restype)
-        assert self.varcolor[op.result] == "red"   # XXX for now
-        return v_res
-
-
-def opname2vstr(name):
-    lls = string_repr.convert_const(name)
-    return inputconst(string_repr.lowleveltype, lls)
+    def originalconcretetype(self, var):
+        return originalconcretetype(self.hannotator.binding(var))

Modified: pypy/dist/pypy/jit/rtimeshift.py
==============================================================================
--- pypy/dist/pypy/jit/rtimeshift.py	(original)
+++ pypy/dist/pypy/jit/rtimeshift.py	Thu Feb  9 21:41:36 2006
@@ -8,8 +8,18 @@
 REDBOX = lltype.GcStruct("redbox", ("genvar", rgenop.CONSTORVAR))
 REDBOX_PTR = lltype.Ptr(REDBOX)
 
+SIGNED_REDBOX = lltype.GcStruct("signed_redbox", 
+                                ('basebox', REDBOX),
+                                ("value", lltype.Signed))
+SIGNED_REDBOX_PTR = lltype.Ptr(SIGNED_REDBOX)
+
 
 def ll_gvar_from_redbox(jitstate, box):
+    if not box.genvar:
+        # XXX other ll types!
+        # XXX support for polymorphism needs rethinking
+        sbox = lltype.cast_pointer(SIGNED_REDBOX_PTR, box)
+        box.genvar = ll_gvar_from_const(jitstate, sbox.value)
     return box.genvar
 
 def ll_gvar_from_const(jitstate, value):

Modified: pypy/dist/pypy/jit/test/test_hint_timeshift.py
==============================================================================
--- pypy/dist/pypy/jit/test/test_hint_timeshift.py	(original)
+++ pypy/dist/pypy/jit/test/test_hint_timeshift.py	Thu Feb  9 21:41:36 2006
@@ -4,7 +4,7 @@
 from pypy.jit.hintbookkeeper import HintBookkeeper
 from pypy.jit.hintmodel import *
 from pypy.jit.hinttimeshift import HintTimeshift
-from pypy.jit import rtimeshift
+from pypy.jit import rtimeshift, hintrtyper
 from pypy.jit.test.test_llabstractinterp import annotation
 from pypy.rpython.lltypesystem import lltype
 from pypy.rpython.objectmodel import hint
@@ -51,26 +51,28 @@
     residual_graph_args = []
     assert len(graph1.getargs()) == 1 + len(values)
     for v, llvalue in zip(graph1.getargs()[1:], values):
-        color = htshift.varcolor[v]
-        if color == "green":
+        r = htshift.hrtyper.bindingrepr(v)
+        residual_v = r.residual_values(llvalue)
+        if len(residual_v) == 0:
+            # green
             graph1args.append(llvalue)
-        elif color == "red":
-            TYPE = htshift.varconcretetype[v]
+        else:
+            # red
+            assert residual_v == [llvalue], "XXX for now"
+            TYPE = htshift.originalconcretetype(v)
             box = rtimeshift.ll_input_redbox(jitstate, TYPE)
             graph1args.append(box)
             residual_graph_args.append(llvalue)
-        else:
-            raise NotImplementedError(color)
     llinterp = LLInterpreter(rtyper)
     result1 = llinterp.eval_graph(graph1, graph1args)
     # now try to run the block produced by the jitstate
-    color = htshift.varcolor[graph1.getreturnvar()]
-    if color == "green":
+    r = htshift.hrtyper.bindingrepr(graph1.getreturnvar())
+    if isinstance(r, hintrtyper.GreenRepr):
         result_gvar = rgenop.genconst(jitstate.curblock, result1)
-    elif color == "red":
+    elif isinstance(r, hintrtyper.RedRepr):
         result_gvar = result1.genvar
     else:
-        raise NotImplementedError(color)
+        raise NotImplementedError(r)
     jitblock = rtimeshift.ll_close_jitstate(jitstate, result_gvar)
     return rgenop.runblock(jitblock, residual_graph_args,
                            viewbefore = conftest.option.view)
@@ -86,3 +88,14 @@
         return x + y
     res = timeshift(ll_function, [5, 7])
     assert res == 12
+
+def test_convert_const_to_redbox():
+    def ll_function(x, y):
+        x = hint(x, concrete=True)
+        tot = 0
+        while x:    # conversion from green '0' to red 'tot'
+            tot += y
+            x -= 1
+        return tot
+    res = timeshift(ll_function, [7, 2])
+    assert res == 14

Modified: pypy/dist/pypy/rpython/rtyper.py
==============================================================================
--- pypy/dist/pypy/rpython/rtyper.py	(original)
+++ pypy/dist/pypy/rpython/rtyper.py	Thu Feb  9 21:41:36 2006
@@ -239,18 +239,6 @@
         assert isinstance(v, Variable)
         v.concretetype = self.bindingrepr(v).lowleveltype
 
-    def typedconstant(self, c, using_repr=None):
-        """Make a copy of the Constant 'c' and give it a concretetype."""
-        assert isinstance(c, Constant)
-        if using_repr is None:
-            using_repr = self.bindingrepr(c)
-        if not hasattr(c, 'concretetype'):
-            c = inputconst(using_repr, c.value)
-        else:
-            if c.concretetype is not Void:
-                assert typeOf(c.value) == using_repr.lowleveltype
-        return c
-
     def setup_block_entry(self, block):
         if block.operations == () and len(block.inputargs) == 2:
             # special case for exception blocks: force them to return an
@@ -269,6 +257,9 @@
                 result.append(r)
             return result
 
+    def make_new_lloplist(self, block):
+        return LowLevelOpList(self, block)
+
     def specialize_block(self, block):
         # give the best possible types to the input args
         try:
@@ -281,7 +272,7 @@
         # specialize all the operations, as far as possible
         if block.operations == ():   # return or except block
             return
-        newops = LowLevelOpList(self, block)
+        newops = self.make_new_lloplist(block)
         varmapping = {}
         for v in block.getvariables():
             varmapping[v] = v    # records existing Variables
@@ -352,24 +343,24 @@
             if isinstance(a, Variable):
                 a.concretetype = self.exceptiondata.lltype_of_exception_type
             elif isinstance(a, Constant):
-                link.last_exception = self.typedconstant(
-                    a, using_repr=self.exceptiondata.r_exception_type)
+                link.last_exception = inputconst(
+                    self.exceptiondata.r_exception_type, a.value)
 
             a = link.last_exc_value
             if isinstance(a, Variable):
                 a.concretetype = self.exceptiondata.lltype_of_exception_value
             elif isinstance(a, Constant):
-                link.last_exc_value = self.typedconstant(
-                    a, using_repr=self.exceptiondata.r_exception_value)
+                link.last_exc_value = inputconst(
+                    self.exceptiondata.r_exception_value, a.value)
 
             inputargs_reprs = self.setup_block_entry(link.target)
-            newops = LowLevelOpList(self, block)
+            newops = self.make_new_lloplist(block)
             newlinkargs = {}
             for i in range(len(link.args)):
                 a1 = link.args[i]
                 r_a2 = inputargs_reprs[i]
                 if isinstance(a1, Constant):
-                    link.args[i] = self.typedconstant(a1, using_repr=r_a2)
+                    link.args[i] = inputconst(r_a2, a1.value)
                     continue   # the Constant was typed, done
                 if a1 is link.last_exception:
                     r_a1 = self.exceptiondata.r_exception_type
@@ -454,6 +445,9 @@
                 resultvar not in varmapping):
                 # fresh Variable: rename it to the previously existing op.result
                 varmapping[resultvar] = op.result
+            elif resultvar is op.result:
+                # special case: we got the previous op.result Variable again
+                assert varmapping[resultvar] is resultvar
             else:
                 # renaming unsafe.  Insert a 'same_as' operation...
                 hop.llops.append(SpaceOperation('same_as', [resultvar],
@@ -523,7 +517,9 @@
         classdef = hop.s_result.classdef
         return rclass.rtype_new_instance(self, classdef, hop.llops)
 
-    def missing_operation(self, hop):
+    generic_translate_operation = None
+
+    def default_translate_operation(self, hop):
         raise TyperError("unimplemented operation: '%s'" % hop.spaceop.opname)
 
     # __________ utilities __________
@@ -613,11 +609,16 @@
         return result
 
     def dispatch(self, opname=None):
-        if not opname:
-            opname = self.spaceop.opname
         rtyper = self.rtyper
+        generic = rtyper.generic_translate_operation
+        if generic is not None:
+            res = generic(self)
+            if res is not None:
+                return res
+        if not opname:
+             opname = self.spaceop.opname
         translate_meth = getattr(rtyper, 'translate_op_'+opname,
-                                 rtyper.missing_operation)
+                                 rtyper.default_translate_operation)
         return translate_meth(self)
 
     def inputarg(self, converted_to, arg):



More information about the Pypy-commit mailing list