[pypy-svn] r37363 - in pypy/dist/pypy/jit/codegen: . dump i386 i386/test llgraph llvm/test ppc/test test

arigo at codespeak.net arigo at codespeak.net
Thu Jan 25 23:26:52 CET 2007


Author: arigo
Date: Thu Jan 25 23:26:50 2007
New Revision: 37363

Modified:
   pypy/dist/pypy/jit/codegen/dump/rgenop.py
   pypy/dist/pypy/jit/codegen/i386/rgenop.py
   pypy/dist/pypy/jit/codegen/i386/test/test_rgenop.py
   pypy/dist/pypy/jit/codegen/llgraph/rgenop.py
   pypy/dist/pypy/jit/codegen/llvm/test/test_rgenop.py
   pypy/dist/pypy/jit/codegen/model.py
   pypy/dist/pypy/jit/codegen/ppc/test/test_rgenop.py
   pypy/dist/pypy/jit/codegen/test/rgenop_tests.py
Log:
Remove the write_frame_var() interface, which is dangerous as it breaks
the basic assumption that "variables == values" everywhere in our flow
graphs.  Replace it with an explicit "place" mechanism.


Modified: pypy/dist/pypy/jit/codegen/dump/rgenop.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/dump/rgenop.py	(original)
+++ pypy/dist/pypy/jit/codegen/dump/rgenop.py	Thu Jan 25 23:26:50 2007
@@ -255,6 +255,24 @@
             self.rgenop.vlistname(vars_gv)))
         return info
 
+    def alloc_frame_place(self, kind, gv_initial_value):
+        place = self.llbuilder.alloc_frame_place(kind, gv_initial_value)
+        self.dump("%s = %s.alloc_frame_place(%s, %s)" % (
+            place,
+            self.name,
+            self.rgenop.kindtokenname(kind),
+            self.rgenop.vname(gv_initial_value)))
+        return place
+
+    def genop_absorb_place(self, kind, place):
+        v = self.llbuilder.genop_absorb_place(kind, place)
+        self.dump("%s = %s.genop_absorb_place(%s, %s)" % (
+            self.rgenop.vname(v),
+            self.name,
+            self.rgenop.kindtokenname(kind),
+            place))
+        return v
+
 
 class RDumpGenOp(llrgenop.RGenOp):
 
@@ -379,8 +397,8 @@
 
     @staticmethod
     @specialize.arg(0)
-    def write_frame_var(T, base, info, index, value):
-        RDumpGenOp.dump("# write_frame_var(info=%s, index=%d)" % (info, index))
-        llrgenop.RGenOp.write_frame_var(T, base, info, index, value)
+    def write_frame_place(T, base, place, value):
+        RDumpGenOp.dump("# write_frame_place(place=%s)" % (place,))
+        llrgenop.RGenOp.write_frame_place(T, base, place, value)
 
 kindtokennames = {}

Modified: pypy/dist/pypy/jit/codegen/i386/rgenop.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/i386/rgenop.py	(original)
+++ pypy/dist/pypy/jit/codegen/i386/rgenop.py	Thu Jan 25 23:26:50 2007
@@ -451,6 +451,12 @@
             result.append(v)
         return result
 
+    def alloc_frame_place(self, kind, gv_initial_value):
+        raise NotImplementedError
+
+    def genop_absorb_place(self, kind, place):
+        raise NotImplementedError
+
 
 class Label(GenLabel):
     targetaddr = 0
@@ -710,7 +716,7 @@
 
     @staticmethod
     @specialize.arg(0)
-    def write_frame_var(T, base, info, index, value):
+    def write_frame_place(T, base, place, value):
         raise NotImplementedError
 
 global_rgenop = RI386GenOp()

Modified: pypy/dist/pypy/jit/codegen/i386/test/test_rgenop.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/i386/test/test_rgenop.py	(original)
+++ pypy/dist/pypy/jit/codegen/i386/test/test_rgenop.py	Thu Jan 25 23:26:50 2007
@@ -53,5 +53,5 @@
 
     #def test_read_frame_var_direct(self):   py.test.skip("in-progress")
     #def test_read_frame_var_compile(self):  py.test.skip("in-progress")
-    def test_write_frame_var_direct(self):  py.test.skip("in-progress")
-    def test_write_frame_var_compile(self): py.test.skip("in-progress")
+    def test_write_frame_place_direct(self):  py.test.skip("in-progress")
+    def test_write_frame_place_compile(self): py.test.skip("in-progress")

Modified: pypy/dist/pypy/jit/codegen/llgraph/rgenop.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/llgraph/rgenop.py	(original)
+++ pypy/dist/pypy/jit/codegen/llgraph/rgenop.py	Thu Jan 25 23:26:50 2007
@@ -46,6 +46,12 @@
         self.b = b
         self.g = g
 
+class LLPlace:
+    absorbed = False
+    def __init__(self, v, info):
+        self.v    = v
+        self.info = info
+
 class LLFlexSwitch(CodeGenSwitch):
     
     def __init__(self, rgenop, b, g, args_gv):
@@ -276,12 +282,31 @@
     # read_frame_var support
 
     def genop_get_frame_base(self):
+        debug_assert(self.rgenop.currently_writing is self,
+                     "genop_get_frame_base: bad currently_writing")
         return LLVar(llimpl.genop(self.b, 'get_frame_base', [],
                                   gv_Address.v))
 
     def get_frame_info(self, vars):
+        debug_assert(self.rgenop.currently_writing is self,
+                     "get_frame_info: bad currently_writing")
         return llimpl.get_frame_info(self.b, vars)
 
+    def alloc_frame_place(self, gv_TYPE, gv_initial_value):
+        debug_assert(self.rgenop.currently_writing is self,
+                     "alloc_frame_place: bad currently_writing")
+        v = LLVar(llimpl.genop(self.b, 'same_as', [gv_initial_value],
+                               gv_TYPE.v))
+        return LLPlace(v, llimpl.get_frame_info(self.b, [v]))
+
+    def genop_absorb_place(self, gv_TYPE, place):
+        debug_assert(self.rgenop.currently_writing is self,
+                     "alloc_frame_place: bad currently_writing")
+        debug_assert(not place.absorbed, "place already absorbed")
+        place.absorbed = True
+        return place.v
+
+
 class RGenOp(AbstractRGenOp):
     gv_Void = gv_Void
     currently_writing = None
@@ -372,8 +397,7 @@
 
     @staticmethod
     @specialize.arg(0)
-    def write_frame_var(T, base, info, index, value):
-        llimpl.write_frame_var(base, info, index, value)
-
+    def write_frame_place(T, base, place, value):
+        llimpl.write_frame_var(base, place.info, 0, value)
 
 rgenop = RGenOp()      # no real point in using a full class in llgraph

Modified: pypy/dist/pypy/jit/codegen/llvm/test/test_rgenop.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/llvm/test/test_rgenop.py	(original)
+++ pypy/dist/pypy/jit/codegen/llvm/test/test_rgenop.py	Thu Jan 25 23:26:50 2007
@@ -27,5 +27,5 @@
 
     test_read_frame_var_direct   = skip
     test_read_frame_var_compile  = skip
-    test_write_frame_var_direct  = skip
-    test_write_frame_var_compile = skip
+    test_write_frame_place_direct  = skip
+    test_write_frame_place_compile = skip

Modified: pypy/dist/pypy/jit/codegen/model.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/model.py	(original)
+++ pypy/dist/pypy/jit/codegen/model.py	Thu Jan 25 23:26:50 2007
@@ -178,15 +178,36 @@
     def genop_get_frame_base(self):
         '''Generate an operation that reads the current stack frame pointer.
         The pointer can later be passed to read_frame_var() and
-        write_frame_var().  This returns a GenVar.
+        write_frame_place().  This returns a GenVar.
         '''
         raise NotImplementedError
 
     def get_frame_info(self, vars_gv):
         '''Return a constant object that describes where the variables are
         inside the stack frame.  The result should be correct for the
-        current basic block.  Clearly, it forces the listed variables to
-        live in the stack instead of being allocated to registers.
+        current basic block.  It forces the listed variables to live in the
+        stack instead of being allocated to registers (or at least to be
+        copied into the stack when get_frame_info is called; a copy is ok
+        because there is no way to change the value of a variable).
+        '''
+        raise NotImplementedError
+
+    def alloc_frame_place(self, kind, gv_initial_value):
+        '''Reserve a "place" in the frame stack where called functions
+        can write to, with write_frame_place().  The place is not valid
+        any more after the current basic block.
+
+        Return value: any object representing the place.
+        '''
+        raise NotImplementedError
+
+    def genop_absorb_place(self, kind, place):
+        '''Absorb a place.  This turns it into a regular variable,
+        containing the last value written into that place.  The place
+        itself is no longer a valid target for write_frame_place()
+        afterwards.
+
+        Return value: a fresh GenVar.
         '''
         raise NotImplementedError
 
@@ -306,9 +327,10 @@
 
     #@staticmethod
     #@specialize.arg(0)
-    #def write_frame_var(T, base, info, index, value):
-    #    """Write into the stack frame of a caller.
-    #    See read_frame_var()."""
+    #def write_frame_place(T, base, place, value):
+    #    """Write into a place in the stack frame of a caller.  The
+    #    'base' is the frame stack pointer captured by the operation
+    #    generated by genop_get_frame_base()."""
 
 
 class CodeGenSwitch(object):

Modified: pypy/dist/pypy/jit/codegen/ppc/test/test_rgenop.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/ppc/test/test_rgenop.py	(original)
+++ pypy/dist/pypy/jit/codegen/ppc/test/test_rgenop.py	Thu Jan 25 23:26:50 2007
@@ -23,5 +23,5 @@
 
     def test_read_frame_var_direct(self):   py.test.skip("in-progress")
     def test_read_frame_var_compile(self):  py.test.skip("in-progress")
-    def test_write_frame_var_direct(self):  py.test.skip("in-progress")
-    def test_write_frame_var_compile(self): py.test.skip("in-progress")
+    def test_write_frame_place_direct(self):  py.test.skip("in-progress")
+    def test_write_frame_place_compile(self): py.test.skip("in-progress")

Modified: pypy/dist/pypy/jit/codegen/test/rgenop_tests.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/test/rgenop_tests.py	(original)
+++ pypy/dist/pypy/jit/codegen/test/rgenop_tests.py	Thu Jan 25 23:26:50 2007
@@ -628,18 +628,6 @@
         self.frameinfo = info
         return llhelper(self.FUNC, self.reader)
 
-class FrameVarWriter:
-    FUNC = lltype.Ptr(lltype.FuncType([llmemory.Address, lltype.Signed],
-                                      lltype.Void))
-    def __init__(self, RGenOp):
-        def writer(base, value):
-            return RGenOp.write_frame_var(lltype.Signed, base,
-                                          self.frameinfo, 0, value)
-        self.writer = writer
-    def get_writer(self, info):
-        self.frameinfo = info
-        return llhelper(self.FUNC, self.writer)
-
 def make_read_frame_var(rgenop, get_reader):
     signed_kind = rgenop.kindToken(lltype.Signed)
     sigtoken = rgenop.sigToken(FUNC)
@@ -670,36 +658,49 @@
         return res
     return read_frame_var_runner
 
-def make_write_frame_var(rgenop, get_writer):
+class FramePlaceWriter:
+    FUNC = lltype.Ptr(lltype.FuncType([llmemory.Address, lltype.Signed],
+                                      lltype.Void))
+    def __init__(self, RGenOp):
+        def writer(base, value):
+            if value > 5:
+                RGenOp.write_frame_place(lltype.Signed, base,
+                                         self.place, value * 7)
+        self.writer = writer
+    def get_writer(self, place):
+        self.place = place
+        return llhelper(self.FUNC, self.writer)
+
+def make_write_frame_place(rgenop, get_writer):
     signed_kind = rgenop.kindToken(lltype.Signed)
     sigtoken = rgenop.sigToken(FUNC)
-    writertoken = rgenop.sigToken(FrameVarWriter.FUNC.TO)
+    writertoken = rgenop.sigToken(FramePlaceWriter.FUNC.TO)
 
     builder, gv_f, [gv_x] = rgenop.newgraph(sigtoken, "f")
     builder.start_writing()
 
-    gv_y = builder.genop_same_as(signed_kind, rgenop.genconst(0))
     gv_base = builder.genop_get_frame_base()
-    info = builder.get_frame_info([gv_y])
-    gv_42 = rgenop.genconst(42)
-    gv_writer = rgenop.constPrebuiltGlobal(get_writer(info))
-    builder.genop_call(writertoken, gv_writer, [gv_base, gv_42])
+    gv_k = rgenop.genconst(-100)
+    place = builder.alloc_frame_place(signed_kind, gv_initial_value=gv_k)
+    gv_writer = rgenop.constPrebuiltGlobal(get_writer(place))
+    builder.genop_call(writertoken, gv_writer, [gv_base, gv_x])
+    gv_y = builder.genop_absorb_place(signed_kind, place)
     builder.finish_and_return(sigtoken, gv_y)
     builder.end()
 
     return gv_f
 
-def get_write_frame_var_runner(RGenOp):
-    fvw = FrameVarWriter(RGenOp)
+def get_write_frame_place_runner(RGenOp):
+    fvw = FramePlaceWriter(RGenOp)
 
-    def write_frame_var_runner(x):
+    def write_frame_place_runner(x):
         rgenop = RGenOp()
-        gv_f = make_write_frame_var(rgenop, fvw.get_writer)
+        gv_f = make_write_frame_place(rgenop, fvw.get_writer)
         fn = gv_f.revealconst(lltype.Ptr(FUNC))
         res = fn(x)
         keepalive_until_here(rgenop)    # to keep the code blocks alive
         return res
-    return write_frame_var_runner
+    return write_frame_place_runner
 
 
 class AbstractRGenOpTests(test_boehm.AbstractGCTestClass):
@@ -1257,20 +1258,24 @@
         res = fn(30)
         assert res == 60
 
-    def test_write_frame_var_direct(self):
-        def get_writer(info):
-            fvw = FrameVarWriter(self.RGenOp)
-            fvw.frameinfo = info
+    def test_write_frame_place_direct(self):
+        def get_writer(place):
+            fvw = FramePlaceWriter(self.RGenOp)
+            fvw.place = place
             writer_ptr = self.directtesthelper(fvw.FUNC, fvw.writer)
             return writer_ptr
 
         rgenop = self.RGenOp()
-        gv_callable = make_write_frame_var(rgenop, get_writer)
+        gv_callable = make_write_frame_place(rgenop, get_writer)
         fnptr = self.cast(gv_callable, 1)
-        res = fnptr(-0xfada)
+        res = fnptr(3)
+        assert res == -100
+        res = fnptr(6)
         assert res == 42
 
-    def test_write_frame_var_compile(self):
-        fn = self.compile(get_write_frame_var_runner(self.RGenOp), [int])
-        res = fn(-1)
-        assert res == 42
+    def test_write_frame_place_compile(self):
+        fn = self.compile(get_write_frame_place_runner(self.RGenOp), [int])
+        res = fn(-42)
+        assert res == -100
+        res = fn(606)
+        assert res == 4242



More information about the Pypy-commit mailing list