[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