[pypy-svn] r31954 - in pypy/dist/pypy: jit/codegen/i386 jit/codegen/i386/test jit/codegen/llgraph jit/codegen/llgraph/test jit/llabstractinterp jit/llabstractinterp/test jit/timeshifter jit/timeshifter/test rpython/lltypesystem
arigo at codespeak.net
arigo at codespeak.net
Sat Sep 2 20:30:43 CEST 2006
Author: arigo
Date: Sat Sep 2 20:30:29 2006
New Revision: 31954
Modified:
pypy/dist/pypy/jit/codegen/i386/ri386genop.py
pypy/dist/pypy/jit/codegen/i386/test/test_ri386genop.py
pypy/dist/pypy/jit/codegen/llgraph/llimpl.py
pypy/dist/pypy/jit/codegen/llgraph/rgenop.py
pypy/dist/pypy/jit/codegen/llgraph/test/test_llimpl.py
pypy/dist/pypy/jit/llabstractinterp/llabstractinterp.py
pypy/dist/pypy/jit/llabstractinterp/llcontainer.py
pypy/dist/pypy/jit/llabstractinterp/llvalue.py
pypy/dist/pypy/jit/llabstractinterp/test/test_jit_tl.py
pypy/dist/pypy/jit/llabstractinterp/test/test_jit_tlr.py
pypy/dist/pypy/jit/llabstractinterp/test/test_llabstractinterp.py
pypy/dist/pypy/jit/llabstractinterp/test/test_vlist.py
pypy/dist/pypy/jit/llabstractinterp/vlist.py
pypy/dist/pypy/jit/timeshifter/oop.py
pypy/dist/pypy/jit/timeshifter/rcontainer.py
pypy/dist/pypy/jit/timeshifter/rtimeshift.py
pypy/dist/pypy/jit/timeshifter/rtyper.py
pypy/dist/pypy/jit/timeshifter/rvalue.py
pypy/dist/pypy/jit/timeshifter/test/test_timeshift.py
pypy/dist/pypy/jit/timeshifter/vlist.py
pypy/dist/pypy/rpython/lltypesystem/lloperation.py
Log:
(pedronis, arigo)
Improved the interface of RGenOp. Now it starts to make sense for real
back-ends, and not to make sense any more for producing llgraphs.
Good trade-off.
Modified: pypy/dist/pypy/jit/codegen/i386/ri386genop.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/i386/ri386genop.py (original)
+++ pypy/dist/pypy/jit/codegen/i386/ri386genop.py Sat Sep 2 20:30:29 2006
@@ -30,11 +30,6 @@
return 'var@%d' % (self.stackpos,)
-class TypeConst(GenConst):
-
- def __init__(self, kind):
- self.kind = kind
-
##class Const(GenConst):
## def revealconst(self, TYPE):
@@ -124,31 +119,80 @@
self.fixedposition = True
return self.startaddr
- def geninputarg(self, gv_TYPE):
+ def geninputarg(self, kind):
res = Var(self.argcount)
self.argcount += 1
self.stackdepth += 1
return res
@specialize.arg(1)
- def genop(self, opname, args_gv, gv_RESTYPE=None):
+ def genop1(self, opname, gv_arg):
genmethod = getattr(self, 'op_' + opname)
- return genmethod(args_gv, gv_RESTYPE)
+ return genmethod(gv_arg)
+
+ @specialize.arg(1)
+ def genop2(self, opname, gv_arg1, gv_arg2):
+ genmethod = getattr(self, 'op_' + opname)
+ return genmethod(gv_arg1, gv_arg2)
def genop_getfield(self, offset, gv_ptr):
- return self.emit_getfield(gv_ptr, offset)
+ # XXX only for int fields
+ self.mc.MOV(edx, gv_ptr.operand(self))
+ return self.returnvar(mem(edx, offset))
def genop_setfield(self, offset, gv_ptr, gv_value):
- return self.emit_setfield(gv_ptr, offset, gv_value)
+ # XXX only for ints for now.
+ self.mc.MOV(eax, gv_value.operand(self))
+ self.mc.MOV(edx, gv_ptr.operand(self))
+ self.mc.MOV(mem(edx, offset), eax)
def genop_getsubstruct(self, offset, gv_ptr):
- return self.emit_getsubstruct(gv_ptr, offset)
+ self.mc.MOV(edx, gv_ptr.operand(self))
+ self.mc.LEA(eax, mem(edx, offset))
+ return self.returnvar(eax)
def genop_getarrayitem(self, arraytoken, gv_ptr, gv_index):
- return self.emit_getarrayitem(gv_ptr, arraytoken, gv_index)
+ # XXX! only works for GcArray(Signed) for now!!
+ lengthoffset, startoffset, itemoffset = arraytoken
+ self.mc.MOV(edx, gv_ptr.operand(self))
+ if isinstance(gv_index, IntConst):
+ startoffset += itemoffset * gv_index.value
+ op = mem(edx, startoffset)
+ elif itemoffset in SIZE2SHIFT:
+ self.mc.MOV(ecx, gv_index.operand(self))
+ op = memSIB(edx, ecx, SIZE2SHIFT[itemoffset], startoffset)
+ else:
+ self.mc.IMUL(ecx, gv_index.operand(self), imm(itemoffset))
+ op = memSIB(edx, ecx, 0, startoffset)
+ return self.returnvar(op)
+
+ def genop_getarraysize(self, arraytoken, gv_ptr):
+ lengthoffset, startoffset, itemoffset = arraytoken
+ self.mc.MOV(edx, gv_ptr.operand(self))
+ return self.returnvar(mem(edx, lengthoffset))
def genop_malloc_fixedsize(self, size):
- return self.emit_malloc_fixedsize(size)
+ # XXX boehm only, no atomic/non atomic distinction for now
+ self.push(imm(size))
+ gc_malloc_ptr = llhelper(GC_MALLOC, gc_malloc)
+ self.mc.CALL(rel32(lltype.cast_ptr_to_int(gc_malloc_ptr)))
+ return self.returnvar(eax)
+
+ def genop_call(self, sigtoken, gv_fnptr, args_gv):
+ for i in range(len(args_gv)-1, -1, -1):
+ gv_arg = args_gv[i]
+ if gv_arg is not None:
+ self.push(gv_arg.operand(self))
+ target = gv_fnptr.revealconst(lltype.Signed)
+ self.mc.CALL(rel32(target))
+ # XXX only for int return_kind
+ return self.returnvar(eax)
+
+ def genop_same_as(self, kind, gv_x):
+ if gv_x.is_const: # must always return a var
+ return self.returnvar(gv_x.operand(self))
+ else:
+ return gv_x
def close1(self):
return Link(self)
@@ -161,6 +205,8 @@
self.mc.JE(rel32(false_block.getstartaddr()))
return Link(false_block), Link(self)
+ # ____________________________________________________________
+
def stack_access(self, stackpos):
return mem(esp, WORD * (self.stackdepth-1 - stackpos))
@@ -173,172 +219,114 @@
self.push(op)
return res
- def op_int_is_true(self, (gv_x,), gv_RESTYPE):
+ def op_int_is_true(self, gv_x):
return gv_x
- def op_int_add(self, (gv_x, gv_y), gv_RESTYPE):
- if isinstance(gv_x, IntConst) and isinstance(gv_y, IntConst):
- # XXX do this for the other operations too
- return IntConst(gv_x.value + gv_y.value)
+ def op_int_add(self, gv_x, gv_y):
self.mc.MOV(eax, gv_x.operand(self))
self.mc.ADD(eax, gv_y.operand(self))
return self.returnvar(eax)
- def op_int_sub(self, (gv_x, gv_y), gv_RESTYPE):
+ def op_int_sub(self, gv_x, gv_y):
self.mc.MOV(eax, gv_x.operand(self))
self.mc.SUB(eax, gv_y.operand(self))
return self.returnvar(eax)
- def op_int_mul(self, (gv_x, gv_y), gv_RESTYPE):
+ def op_int_mul(self, gv_x, gv_y):
self.mc.MOV(eax, gv_x.operand(self))
self.mc.IMUL(eax, gv_y.operand(self))
return self.returnvar(eax)
- def op_int_floordiv(self, (gv_x, gv_y), gv_RESTYPE):
+ def op_int_floordiv(self, gv_x, gv_y):
self.mc.MOV(eax, gv_x.operand(self))
self.mc.CDQ()
self.mc.MOV(ecx, gv_y.operand(self))
self.mc.IDIV(ecx)
return self.returnvar(eax)
- def op_int_and(self, (gv_x, gv_y), gv_RESTYPE):
+ def op_int_and(self, gv_x, gv_y):
self.mc.MOV(eax, gv_x.operand(self))
self.mc.AND(eax, gv_y.operand(self))
return self.returnvar(eax)
- def op_int_or(self, (gv_x, gv_y), gv_RESTYPE):
+ def op_int_or(self, gv_x, gv_y):
self.mc.MOV(eax, gv_x.operand(self))
self.mc.OR(eax, gv_y.operand(self))
return self.returnvar(eax)
- def op_int_xor(self, (gv_x, gv_y), gv_RESTYPE):
+ def op_int_xor(self, gv_x, gv_y):
self.mc.MOV(eax, gv_x.operand(self))
self.mc.XOR(eax, gv_y.operand(self))
return self.returnvar(eax)
- def op_int_lt(self, (gv_x, gv_y), gv_RESTYPE):
+ def op_int_lt(self, gv_x, gv_y):
self.mc.MOV(eax, gv_x.operand(self))
self.mc.CMP(eax, gv_y.operand(self))
self.mc.SETL(al)
self.mc.MOVZX(eax, al)
return self.returnvar(eax)
- def op_int_le(self, (gv_x, gv_y), gv_RESTYPE):
+ def op_int_le(self, gv_x, gv_y):
self.mc.MOV(eax, gv_x.operand(self))
self.mc.CMP(eax, gv_y.operand(self))
self.mc.SETLE(al)
self.mc.MOVZX(eax, al)
return self.returnvar(eax)
- def op_int_eq(self, (gv_x, gv_y), gv_RESTYPE):
+ def op_int_eq(self, gv_x, gv_y):
self.mc.MOV(eax, gv_x.operand(self))
self.mc.CMP(eax, gv_y.operand(self))
self.mc.SETE(al)
self.mc.MOVZX(eax, al)
return self.returnvar(eax)
- def op_int_ne(self, (gv_x, gv_y), gv_RESTYPE):
+ def op_int_ne(self, gv_x, gv_y):
self.mc.MOV(eax, gv_x.operand(self))
self.mc.CMP(eax, gv_y.operand(self))
self.mc.SETNE(al)
self.mc.MOVZX(eax, al)
return self.returnvar(eax)
- def op_int_gt(self, (gv_x, gv_y), gv_RESTYPE):
+ def op_int_gt(self, gv_x, gv_y):
self.mc.MOV(eax, gv_x.operand(self))
self.mc.CMP(eax, gv_y.operand(self))
self.mc.SETG(al)
self.mc.MOVZX(eax, al)
return self.returnvar(eax)
- def op_int_ge(self, (gv_x, gv_y), gv_RESTYPE):
+ def op_int_ge(self, gv_x, gv_y):
self.mc.MOV(eax, gv_x.operand(self))
self.mc.CMP(eax, gv_y.operand(self))
self.mc.SETGE(al)
self.mc.MOVZX(eax, al)
return self.returnvar(eax)
- def op_int_neg(self, (gv_x,), gv_RESTYPE):
+ def op_int_neg(self, gv_x):
self.mc.MOV(eax, gv_x.operand(self))
self.mc.NEG(eax)
return self.returnvar(eax)
- def op_int_lshift(self, (gv_x, gv_y), gv_RESTYPE):
+ def op_int_lshift(self, gv_x, gv_y):
self.mc.MOV(eax, gv_x.operand(self))
self.mc.MOV(ecx, gv_y.operand(self))
self.mc.SHL(eax, cl)
return self.returnvar(eax)
- def op_int_rshift(self, (gv_x, gv_y), gv_RESTYPE):
+ def op_int_rshift(self, gv_x, gv_y):
self.mc.MOV(eax, gv_x.operand(self))
self.mc.MOV(ecx, gv_y.operand(self))
self.mc.SHR(eax, cl)
return self.returnvar(eax)
- def op_bool_not(self, (gv_x,), gv_RESTYPE):
- if isinstance(gv_x, IntConst):
- return IntConst(not gv_x.value)
+ def op_bool_not(self, gv_x):
self.mc.CMP(gv_x.operand(self), imm8(0))
self.mc.SETE(al)
self.mc.MOVZX(eax, al)
return self.returnvar(eax)
- def op_cast_pointer(self, (gv_x,), gv_RESTYPE):
- return gv_x
-
- def op_same_as(self, (gv_x,), gv_RESTYPE):
- if gv_x.is_const: # must always return a var
- return self.returnvar(gv_x.operand(self))
- else:
- return gv_x
-
- def emit_malloc_fixedsize(self, size):
- # XXX boehm only, no atomic/non atomic distinction for now
- self.push(imm(size))
- gc_malloc_ptr = llhelper(GC_MALLOC, gc_malloc)
- self.mc.CALL(rel32(lltype.cast_ptr_to_int(gc_malloc_ptr)))
- return self.returnvar(eax)
-
- def emit_getfield(self, gv_ptr, offset):
- # XXX only for int fields
- self.mc.MOV(edx, gv_ptr.operand(self))
- return self.returnvar(mem(edx, offset))
-
- def emit_setfield(self, gv_ptr, offset, gv_value):
- # XXX only for ints for now.
- self.mc.MOV(eax, gv_value.operand(self))
- self.mc.MOV(edx, gv_ptr.operand(self))
- self.mc.MOV(mem(edx, offset), eax)
-
- def emit_getsubstruct(self, gv_ptr, offset):
- self.mc.MOV(edx, gv_ptr.operand(self))
- self.mc.LEA(eax, mem(edx, offset))
- return self.returnvar(eax)
-
- def emit_getarrayitem(self, gv_ptr, arraytoken, gv_index):
- # XXX! only works for GcArray(Signed) for now!!
- lengthoffset, startoffset, itemoffset = arraytoken
- self.mc.MOV(edx, gv_ptr.operand(self))
- if isinstance(gv_index, IntConst):
- startoffset += itemoffset * gv_index.value
- op = mem(edx, startoffset)
- elif itemoffset in SIZE2SHIFT:
- self.mc.MOV(ecx, gv_index.operand(self))
- op = memSIB(edx, ecx, SIZE2SHIFT[itemoffset], startoffset)
- else:
- self.mc.IMUL(ecx, gv_index.operand(self), imm(itemoffset))
- op = memSIB(edx, ecx, 0, startoffset)
- return self.returnvar(op)
-
- def op_getarraysize(self, (gv_ptr,), gv_RESTYPE):
- # XXX! only works for GcArray(Signed) for now!!
- A = DUMMY_A
- lengthoffset, startoffset, itemoffset = self.rgenop.arrayToken(A)
- self.mc.MOV(edx, gv_ptr.operand(self))
- return self.returnvar(mem(edx, lengthoffset))
-
def op_setarrayitem(self, (gv_ptr, gv_index, gv_value), gv_RESTYPE):
# XXX! only works for GcArray(Signed) for now!!
+ XXX-fixme
A = DUMMY_A
lengthoffset, startoffset, itemoffset = self.rgenop.arrayToken(A)
self.mc.MOV(eax, gv_value.operand(self))
@@ -354,17 +342,6 @@
op = memSIB(edx, ecx, 0, startoffset)
self.mc.MOV(op, eax)
- def op_direct_call(self, args_gv, result_kind):
- for i in range(len(args_gv)-1, 0, -1):
- gv_arg = args_gv[i]
- if gv_arg is not None:
- self.push(gv_arg.operand(self))
- gv_fnptr = args_gv[0]
- target = gv_fnptr.revealconst(lltype.Signed)
- self.mc.CALL(rel32(target))
- # XXX only for int return_kind
- return self.returnvar(eax)
-
DUMMY_A = lltype.GcArray(lltype.Signed)
SIZE2SHIFT = {1: 0,
@@ -456,9 +433,6 @@
class RI386GenOp(AbstractRGenOp):
from pypy.jit.codegen.i386.codebuf import MachineCodeBlock
-
- gv_IntWord = TypeConst('IntWord')
- gv_Void = TypeConst('Void')
def __init__(self):
self.mcs = [] # machine code blocks where no-one is currently writing
@@ -520,24 +494,18 @@
@staticmethod
@specialize.memo()
- def kindToken(T): # xxx simplify
- if T is lltype.Void:
- return RI386GenOp.gv_Void
- else:
- return RI386GenOp.gv_IntWord # XXX for now
-
-
- constPrebuiltGlobal = genconst
-
- constTYPE = kindToken
+ def kindToken(T):
+ return None # for now
@staticmethod
@specialize.memo()
- def constFieldName(T, name):
- return IntConst(llmemory.offsetof(T, name))
+ def sigToken(FUNCTYPE):
+ return None # for now
+
+ constPrebuiltGlobal = genconst
- def gencallableconst(self, name, block, gv_FUNCTYPE):
+ def gencallableconst(self, sigtoken, name, block):
prologue = self.newblock()
#prologue.mc.BREAKPOINT()
# re-push the arguments so that they are after the return value
Modified: pypy/dist/pypy/jit/codegen/i386/test/test_ri386genop.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/i386/test/test_ri386genop.py (original)
+++ pypy/dist/pypy/jit/codegen/i386/test/test_ri386genop.py Sat Sep 2 20:30:29 2006
@@ -15,17 +15,15 @@
def make_adder(rgenop, n):
# 'return x+n'
- gv_SIGNED = rgenop.constTYPE(lltype.Signed)
+ signed_kind = rgenop.kindToken(lltype.Signed)
block = rgenop.newblock()
- gv_x = block.geninputarg(gv_SIGNED)
- args_gv = [gv_x,
- rgenop.genconst(n)]
- gv_result = block.genop("int_add", args_gv, gv_SIGNED)
+ gv_x = block.geninputarg(signed_kind)
+ gv_result = block.genop2("int_add", gv_x, rgenop.genconst(n))
link = block.close1()
link.closereturn(gv_result)
- gv_FUNC = rgenop.constTYPE(FUNC)
- gv_add_one = rgenop.gencallableconst("adder", block, gv_FUNC)
+ sigtoken = rgenop.sigToken(FUNC)
+ gv_add_one = rgenop.gencallableconst(sigtoken, "adder", block)
return gv_add_one
def runner(x, y):
@@ -63,29 +61,26 @@
def make_dummy(rgenop):
# 'return x - (y - (x-1))'
- gv_SIGNED = rgenop.constTYPE(lltype.Signed)
+ signed_kind = rgenop.kindToken(lltype.Signed)
block = rgenop.newblock()
- gv_x = block.geninputarg(gv_SIGNED)
- gv_y = block.geninputarg(gv_SIGNED)
- args_gv = [gv_x, rgenop.genconst(1)]
- gv_z = block.genop("int_sub", args_gv, gv_SIGNED)
+ gv_x = block.geninputarg(signed_kind)
+ gv_y = block.geninputarg(signed_kind)
+ gv_z = block.genop2("int_sub", gv_x, rgenop.genconst(1))
link = block.close1()
block2 = rgenop.newblock()
- gv_y2 = block2.geninputarg(gv_SIGNED)
- gv_z2 = block2.geninputarg(gv_SIGNED)
- gv_x2 = block2.geninputarg(gv_SIGNED)
+ gv_y2 = block2.geninputarg(signed_kind)
+ gv_z2 = block2.geninputarg(signed_kind)
+ gv_x2 = block2.geninputarg(signed_kind)
link.close([gv_y, gv_z, gv_x], block2)
- args_gv = [gv_y2, gv_z2]
- gv_s2 = block2.genop("int_sub", args_gv, gv_SIGNED)
- args_gv = [gv_x2, gv_s2]
- gv_t2 = block2.genop("int_sub", args_gv, gv_SIGNED)
+ gv_s2 = block2.genop2("int_sub", gv_y2, gv_z2)
+ gv_t2 = block2.genop2("int_sub", gv_x2, gv_s2)
link2 = block2.close1()
link2.closereturn(gv_t2)
- gv_FUNC2 = rgenop.constTYPE(FUNC2)
- gv_dummyfn = rgenop.gencallableconst("dummy", block, gv_FUNC2)
+ sigtoken = rgenop.sigToken(FUNC2)
+ gv_dummyfn = rgenop.gencallableconst(sigtoken, "dummy", block)
return gv_dummyfn
def dummy_runner(x, y):
@@ -122,30 +117,28 @@
def make_branching(rgenop):
# 'if x > 5: return x-1
# else: return y'
- gv_SIGNED = rgenop.constTYPE(lltype.Signed)
- gv_BOOL = rgenop.constTYPE(lltype.Bool)
+ signed_kind = rgenop.kindToken(lltype.Signed)
block = rgenop.newblock()
- gv_x = block.geninputarg(gv_SIGNED)
- gv_y = block.geninputarg(gv_SIGNED)
- args_gv = [gv_x, rgenop.genconst(5)]
- gv_cond = block.genop("int_gt", args_gv, gv_BOOL)
+ gv_x = block.geninputarg(signed_kind)
+ gv_y = block.geninputarg(signed_kind)
+ gv_cond = block.genop2("int_gt", gv_x, rgenop.genconst(5))
link_false, link_true = block.close2(gv_cond)
block2 = rgenop.newblock()
- gv_one = block2.geninputarg(gv_SIGNED)
- gv_x2 = block2.geninputarg(gv_SIGNED)
- gv_y2 = block2.geninputarg(gv_SIGNED)
+ gv_one = block2.geninputarg(signed_kind)
+ gv_x2 = block2.geninputarg(signed_kind)
+ gv_y2 = block2.geninputarg(signed_kind)
link_true.close([rgenop.genconst(1), gv_x, gv_y], block2)
- args_gv = [gv_x2, gv_one]
- gv_s2 = block2.genop("int_sub", args_gv, gv_SIGNED)
+ gv_s2 = block2.genop2("int_sub", gv_x2, gv_one)
link2 = block2.close1()
link2.closereturn(gv_s2)
link_false.closereturn(gv_y)
- gv_FUNC2 = rgenop.constTYPE(FUNC2)
- gv_branchingfn = rgenop.gencallableconst("branching", block, gv_FUNC2)
+ sigtoken = rgenop.sigToken(FUNC2)
+ gv_branchingfn = rgenop.gencallableconst(sigtoken,
+ "branching", block)
return gv_branchingfn
def branching_runner(x, y):
Modified: pypy/dist/pypy/jit/codegen/llgraph/llimpl.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/llgraph/llimpl.py (original)
+++ pypy/dist/pypy/jit/codegen/llgraph/llimpl.py Sat Sep 2 20:30:29 2006
@@ -13,6 +13,7 @@
from pypy.rpython.extregistry import ExtRegistryEntry
from pypy.rpython.llinterp import LLInterpreter
from pypy.rpython.lltypesystem.rclass import fishllattr
+from pypy.rpython.lltypesystem.lloperation import llop
# for debugging, sanity checks in non-RPython code
@@ -96,17 +97,34 @@
opname = LLSupport.from_rstr(opname)
block = from_opaque_object(blockcontainer.obj)
assert block.exits == [], "block already closed"
- if isinstance(gv_RESULT_TYPE, lltype.LowLevelType):
+ opvars = _inputvars(vars_gv)
+ if gv_RESULT_TYPE is guess:
+ RESULT_TYPE = guess_result_type(opname, opvars)
+ elif isinstance(gv_RESULT_TYPE, lltype.LowLevelType):
RESULT_TYPE = gv_RESULT_TYPE
else:
RESULT_TYPE = from_opaque_object(gv_RESULT_TYPE).value
- opvars = _inputvars(vars_gv)
v = flowmodel.Variable()
v.concretetype = RESULT_TYPE
op = flowmodel.SpaceOperation(opname, opvars, v)
block.operations.append(op)
return to_opaque_object(erasedvar(v, block))
+def guess_result_type(opname, opvars):
+ op = getattr(llop, opname)
+ need_result_type = getattr(op.fold, 'need_result_type', False)
+ assert not need_result_type, ("cannot guess the result type of %r"
+ % (opname,))
+ examples = []
+ for v in opvars:
+ example = v.concretetype._example()
+ if isinstance(v.concretetype, lltype.Primitive):
+ if example == 0:
+ example = type(example)(1) # to avoid ZeroDivisionError
+ examples.append(example)
+ result = op.fold(*examples)
+ return lltype.typeOf(result)
+
def gencallableconst(name, targetcontainer, gv_FUNCTYPE):
# 'name' is just a way to track things
if not isinstance(name, str):
@@ -327,7 +345,8 @@
nulllink = lltype.nullptr(LINK.TO)
gv_Void = constTYPE(lltype.Void)
-dummy_placeholder = placeholder("dummy")
+dummy_placeholder = placeholder(None)
+guess = placeholder('guess')
# helpers
@@ -384,4 +403,4 @@
# XXX(for now) void constant constructors
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(placeholder, s_ConstOrVar, specialize_as_constant=True)
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 Sat Sep 2 20:30:29 2006
@@ -26,6 +26,7 @@
return repr(RGenOp.reveal(self))
gv_Void = LLConst(llimpl.constTYPE(lltype.Void))
+gv_dummy_placeholder = LLConst(llimpl.dummy_placeholder)
class LLBlock(CodeGenBlock):
@@ -35,10 +36,29 @@
def geninputarg(self, gv_TYPE):
return LLVar(llimpl.geninputarg(self.b, gv_TYPE.v))
+## @specialize.arg(1)
+## def genop(self, opname, vars_gv, gv_RESULT_TYPE=None):
+## return LLVar(llimpl.genop(self.b, opname, vars_gv,
+## (gv_RESULT_TYPE or gv_Void).v))
+
+ @specialize.arg(1)
+ def genop1(self, opname, gv_arg):
+ return LLVar(llimpl.genop(self.b, opname, [gv_arg], llimpl.guess))
+
@specialize.arg(1)
- def genop(self, opname, vars_gv, gv_RESULT_TYPE=None):
- return LLVar(llimpl.genop(self.b, opname, vars_gv,
- (gv_RESULT_TYPE or gv_Void).v))
+ def genop2(self, opname, gv_arg1, gv_arg2):
+ return LLVar(llimpl.genop(self.b, opname, [gv_arg1, gv_arg2],
+ llimpl.guess))
+
+ def genop_call(self, (ARGS_gv, gv_RESULT, _), gv_callable, args_gv):
+ vars_gv = [gv_callable]
+ for i in range(len(ARGS_gv)):
+ gv_arg = args_gv[i]
+ if gv_arg is not None:
+ gv_arg = LLVar(llimpl.cast(self.b, ARGS_gv[i].v, gv_arg.v))
+ vars_gv.append(gv_arg)
+ # XXX indirect_call later
+ return LLVar(llimpl.genop(self.b, 'direct_call', vars_gv, gv_RESULT.v))
def genop_getfield(self, (gv_name, gv_PTRTYPE, gv_FIELDTYPE), gv_ptr):
vars_gv = [llimpl.cast(self.b, gv_PTRTYPE.v, gv_ptr.v), gv_name.v]
@@ -63,11 +83,23 @@
return LLVar(llimpl.genop(self.b, 'getarrayitem', vars_gv,
gv_ITEMTYPE.v))
+ def genop_getarraysize(self, gv_ITEMTYPE, gv_ptr):
+ return LLVar(llimpl.genop(self.b, 'getarraysize', [gv_ptr.v],
+ llimpl.constTYPE(lltype.Signed)))
+
def genop_malloc_fixedsize(self, (gv_TYPE, gv_PTRTYPE)):
vars_gv = [gv_TYPE.v]
return LLVar(llimpl.genop(self.b, 'malloc', vars_gv,
gv_PTRTYPE.v))
-
+
+ def genop_malloc_varsize(self, (gv_TYPE, gv_PTRTYPE), gv_length):
+ vars_gv = [gv_TYPE.v, gv_length.v]
+ return LLVar(llimpl.genop(self.b, 'malloc_varsize', vars_gv,
+ gv_PTRTYPE.v))
+
+ def genop_same_as(self, gv_TYPE, gv_value):
+ return LLVar(gv_value.v)
+
def close1(self):
return LLLink(llimpl.closeblock1(self.b))
@@ -84,7 +116,8 @@
llimpl.closelink(self.l, vars_gv, targetblock.b)
def closereturn(self, gv_returnvar):
- llimpl.closereturnlink(self.l, gv_returnvar.v)
+ llimpl.closereturnlink(self.l,
+ (gv_returnvar or gv_dummy_placeholder).v)
class RGenOp(AbstractRGenOp):
@@ -94,7 +127,8 @@
return LLBlock(llimpl.newblock())
# XXX what kind of type/kind information does this need?
- def gencallableconst(self, name, targetblock, gv_FUNCTYPE):
+ def gencallableconst(self, (ARGS_gv, gv_RESULT, gv_FUNCTYPE), name,
+ targetblock):
return LLConst(llimpl.gencallableconst(name, targetblock.b,
gv_FUNCTYPE.v))
@@ -130,22 +164,12 @@
def arrayToken(A):
return LLConst(llimpl.constTYPE(A.OF))
-
@staticmethod
@specialize.memo()
- def constTYPE(T):
- return LLConst(llimpl.constTYPE(T))
-
- @staticmethod
- @specialize.arg(0)
- def placeholder(dummy):
- return LLConst(llimpl.placeholder(dummy))
-
- @staticmethod
- @specialize.memo()
- def constFieldName(T, name):
- assert name in T._flds
- return LLConst(llimpl.constFieldName(name))
+ def sigToken(FUNCTYPE):
+ return ([LLConst(llimpl.constTYPE(A)) for A in FUNCTYPE.ARGS],
+ LLConst(llimpl.constTYPE(FUNCTYPE.RESULT)),
+ LLConst(llimpl.constTYPE(FUNCTYPE)))
constPrebuiltGlobal = genconst
Modified: pypy/dist/pypy/jit/codegen/llgraph/test/test_llimpl.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/llgraph/test/test_llimpl.py (original)
+++ pypy/dist/pypy/jit/codegen/llgraph/test/test_llimpl.py Sat Sep 2 20:30:29 2006
@@ -135,14 +135,6 @@
assert c.concretetype == lltype.Void
assert c.value == lltype.Signed
- def dummy():
- return placeholder(None)
- res = interpret(dummy, [])
- c = from_opaque_object(res)
- assert isinstance(c, flowmodel.Constant)
- assert c.concretetype == lltype.Void
- assert c.value == None
-
def test_rtype_revealcosnt():
def hide_and_reveal(v):
gv = genconst(v)
Modified: pypy/dist/pypy/jit/llabstractinterp/llabstractinterp.py
==============================================================================
--- pypy/dist/pypy/jit/llabstractinterp/llabstractinterp.py (original)
+++ pypy/dist/pypy/jit/llabstractinterp/llabstractinterp.py Sat Sep 2 20:30:29 2006
@@ -160,7 +160,8 @@
class LLAbstractInterp(object):
- def __init__(self, policy=best_policy):
+ def __init__(self, rtyper, policy=best_policy):
+ self.rtyper = rtyper
self.graphs = []
self.graphstates = {} # {origgraph: {BlockState: GraphState}}
self.blocks = {} # {BlockState.key(): list-of-LLBlockStates}
@@ -276,8 +277,11 @@
assert isinstance(v2, (AVariable, AConstant))
if isinstance(v2, AConstant):
# sanity check violating encapsulation
- v1 = rgenop.reveal(v1)
- assert v1.value == v2.value
+ if v2.concretetype is lltype.Void:
+ assert v1 is None
+ else:
+ v1 = rgenop.reveal(v1)
+ assert v1.value == v2.value
else:
args.append(v1)
self.link.close(args, block)
@@ -541,18 +545,36 @@
ls.link = cases[ls.exitcase]
return b
- def genop(self, opname, args, RESULT_TYPE=lltype.Void):
- return self.newblock.genop(opname, args,
- rgenop.constTYPE(RESULT_TYPE))
+## def genop(self, opname, args, RESULT_TYPE=lltype.Void):
+## return self.newblock.genop(opname, args,
+## rgenop.constTYPE(RESULT_TYPE))
- def genconst(self, llvalue):
- return rgenop.genconst(llvalue)
+ def genop1(self, opname, arg):
+ return self.newblock.genop1(opname, arg)
+
+ def genop2(self, opname, arg1, arg2):
+ return self.newblock.genop2(opname, arg1, arg2)
+
+ def genop_call(self, sigtoken, v_callable, args_v):
+ return self.newblock.genop_call(sigtoken, v_callable, args_v)
+
+ def genop_malloc_fixedsize(self, alloctoken):
+ return self.newblock.genop_malloc_fixedsize(alloctoken)
- def genvoidconst(self, placeholder):
- return rgenop.placeholder(placeholder)
+ def genop_malloc_varsize(self, alloctoken, v_length):
+ return self.newblock.genop_malloc_varsize(alloctoken, v_length)
- def constTYPE(self, T):
- return T
+ def genop_getfield(self, fieldtoken, v_ptr):
+ return self.newblock.genop_getfield(fieldtoken, v_ptr)
+
+ def genop_setfield(self, fieldtoken, v_ptr, v_value):
+ return self.newblock.genop_setfield(fieldtoken, v_ptr, v_value)
+
+ def genop_getsubstruct(self, fieldtoken, v_ptr):
+ return self.newblock.genop_getsubstruct(fieldtoken, v_ptr)
+
+ def genconst(self, llvalue):
+ return rgenop.genconst(llvalue)
def binding(self, v):
assert isinstance(v, (Constant, Variable))
@@ -595,20 +617,27 @@
return a_result
def residual(self, op, args_a):
- T= op.result.concretetype
- retvar = self.genop(op.opname,
- [a.forcegenvarorconst(self) for a in args_a],
- T)
+ T = op.result.concretetype
+ args_v = [a.forcegenvarorconst(self) for a in args_a]
+ if op.opname == 'direct_call':
+ sigtoken = rgenop.sigToken(args_a[0].getconcretetype().TO)
+ retvar = self.genop_call(sigtoken, args_v[0], args_v[1:])
+ elif op.opname == 'getfield':
+ fieldtoken = rgenop.fieldToken(args_a[0].getconcretetype().TO,
+ op.args[1].value)
+ retvar = self.genop_getfield(fieldtoken, args_v[0])
+ else:
+ # generic version
+ genopmeth = getattr(self, 'genop%d' % len(args_a))
+ retvar = genopmeth(op.opname, *args_v)
return LLAbstractValue(AVariable(T, genvar=retvar))
def residual_direct_call(self, FUNCTYPE, name, target, args_a):
T = FUNCTYPE.RESULT
- gen_fn_const = rgenop.gencallableconst(name,
- target,
- rgenop.constTYPE(FUNCTYPE))
- retvar = self.genop('direct_call', [gen_fn_const] +
- [a.forcegenvarorconst(self) for a in args_a],
- T)
+ sigtoken = rgenop.sigToken(FUNCTYPE)
+ gen_fn_const = rgenop.gencallableconst(sigtoken, name, target)
+ retvar = self.genop_call(sigtoken, gen_fn_const,
+ [a.forcegenvarorconst(self) for a in args_a])
return LLAbstractValue(AVariable(T, genvar=retvar))
Modified: pypy/dist/pypy/jit/llabstractinterp/llcontainer.py
==============================================================================
--- pypy/dist/pypy/jit/llabstractinterp/llcontainer.py (original)
+++ pypy/dist/pypy/jit/llabstractinterp/llcontainer.py Sat Sep 2 20:30:29 2006
@@ -52,19 +52,16 @@
RESULT_TYPE = lltype.Ptr(self.T)
if self.a_parent is not None:
PARENT_TYPE = self.a_parent.getconcretetype().TO
- parentindex = rgenop.constFieldName(PARENT_TYPE, self.parentindex)
+ fieldtoken = rgenop.fieldToken(PARENT_TYPE, self.parentindex)
v_parent = self.a_parent.forcegenvarorconst(builder)
- v_result = builder.genop('getsubstruct',
- [v_parent, parentindex], RESULT_TYPE)
+ v_result = builder.genop_getsubstruct(fieldtoken, v_parent)
else:
- t = rgenop.constTYPE(self.T)
+ t = rgenop.allocToken(self.T)
if self.T._is_varsize():
- v_result = builder.genop('malloc_varsize',
- [t,
- builder.genconst(self.length)],
- RESULT_TYPE)
+ c_length = builder.genconst(self.length)
+ v_result = builder.genop_malloc_varsize(t, c_length)
else:
- v_result = builder.genop('malloc', [t], RESULT_TYPE)
+ v_result = builder.genop_malloc_fixedsize(t)
self.buildcontent(builder, v_result)
return v_result
@@ -76,10 +73,8 @@
T = self.fieldtype(name)
if isinstance(T, lltype.ContainerType):
# initialize the substructure/subarray
- c_name = rgenop.constFieldName(self.T, name)
- v_subptr = builder.genop('getsubstruct',
- [v_target, c_name],
- lltype.Ptr(T))
+ fieldtoken = rgenop.fieldToken(self.T, name)
+ v_subptr = builder.genop_getsubstruct(fieldtoken, v_target)
assert isinstance(a_value.content, LLVirtualContainer)
a_value.content.buildcontent(builder, v_subptr)
else:
@@ -167,9 +162,8 @@
return getattr(self.T, name)
def setop(self, builder, v_target, name, v_value):
- c_name = rgenop.constFieldName(self.T, name)
- builder.genop('setfield', [v_target, c_name, v_value],
- lltype.Void)
+ fieldtoken = rgenop.fieldToken(self.T, name)
+ builder.genop_setfield(fieldtoken, v_target, v_value)
class LLVirtualArray(LLVirtualContainer):
Modified: pypy/dist/pypy/jit/llabstractinterp/llvalue.py
==============================================================================
--- pypy/dist/pypy/jit/llabstractinterp/llvalue.py (original)
+++ pypy/dist/pypy/jit/llabstractinterp/llvalue.py Sat Sep 2 20:30:29 2006
@@ -16,11 +16,9 @@
Hashable.__init__(self, value)
self.concretetype = T or lltype.typeOf(value)
self.genvar = genvar
- if T is lltype.Void and self.genvar is None:
- self.genvar = rgenop.placeholder(value)
-
+
def getgenvar(self, builder):
- if self.genvar is None:
+ if self.genvar is None and self.concretetype is not lltype.Void:
self.genvar = builder.genconst(self.value)
return self.genvar
@@ -202,7 +200,7 @@
assert c.concretetype == self.concretetype
result = LLAbstractValue(c)
else:
- gen_v = block.geninputarg(rgenop.constTYPE(self.concretetype))
+ gen_v = block.geninputarg(rgenop.kindToken(self.concretetype))
result = LLAbstractValue(AVariable(self.concretetype, genvar=gen_v))
result.origin.append(self)
return result
Modified: pypy/dist/pypy/jit/llabstractinterp/test/test_jit_tl.py
==============================================================================
--- pypy/dist/pypy/jit/llabstractinterp/test/test_jit_tl.py (original)
+++ pypy/dist/pypy/jit/llabstractinterp/test/test_jit_tl.py Sat Sep 2 20:30:29 2006
@@ -17,11 +17,12 @@
#inline.auto_inlining(t, 0.3)
mod.graph1 = t.graphs[0]
+ mod.rtyper = rtyper
mod.llinterp = LLInterpreter(rtyper)
def jit_tl(code):
- interp = LLAbstractInterp()
+ interp = LLAbstractInterp(rtyper)
hints = {0: string_repr.convert_const(code),
1: 0}
graph2 = interp.eval(graph1, hints)
Modified: pypy/dist/pypy/jit/llabstractinterp/test/test_jit_tlr.py
==============================================================================
--- pypy/dist/pypy/jit/llabstractinterp/test/test_jit_tlr.py (original)
+++ pypy/dist/pypy/jit/llabstractinterp/test/test_jit_tlr.py Sat Sep 2 20:30:29 2006
@@ -15,7 +15,7 @@
rtyper = t.buildrtyper()
rtyper.specialize()
- interp = LLAbstractInterp()
+ interp = LLAbstractInterp(rtyper)
hints = {0: string_repr.convert_const(tlr.SQUARE)}
graph2 = interp.eval(t.graphs[0], hints)
#graph2.show()
Modified: pypy/dist/pypy/jit/llabstractinterp/test/test_llabstractinterp.py
==============================================================================
--- pypy/dist/pypy/jit/llabstractinterp/test/test_llabstractinterp.py (original)
+++ pypy/dist/pypy/jit/llabstractinterp/test/test_llabstractinterp.py Sat Sep 2 20:30:29 2006
@@ -34,7 +34,7 @@
rtyper = t.buildrtyper()
rtyper.specialize()
# build the residual ll graphs by propagating the hints
- interp = LLAbstractInterp(policy)
+ interp = LLAbstractInterp(rtyper, policy)
hints = {}
for hint in arghints:
hints[hint] = argvalues[hint]
Modified: pypy/dist/pypy/jit/llabstractinterp/test/test_vlist.py
==============================================================================
--- pypy/dist/pypy/jit/llabstractinterp/test/test_vlist.py (original)
+++ pypy/dist/pypy/jit/llabstractinterp/test/test_vlist.py Sat Sep 2 20:30:29 2006
@@ -16,7 +16,7 @@
rtyper.specialize()
graph1 = t.graphs[0]
- interp = LLAbstractInterp(policy)
+ interp = LLAbstractInterp(rtyper, policy)
hints = {}
llvalues = []
for i, value in enumerate(argvalues):
Modified: pypy/dist/pypy/jit/llabstractinterp/vlist.py
==============================================================================
--- pypy/dist/pypy/jit/llabstractinterp/vlist.py (original)
+++ pypy/dist/pypy/jit/llabstractinterp/vlist.py Sat Sep 2 20:30:29 2006
@@ -3,6 +3,7 @@
from pypy.jit.llabstractinterp.llvalue import LLAbstractValue, AConstant
from pypy.jit.llabstractinterp.llvalue import ll_dummy_value
from pypy.jit.llabstractinterp.llcontainer import LLAbstractContainer
+from pypy.jit.codegen.llgraph.rgenop import rgenop
class LLVirtualList(LLAbstractContainer):
@@ -40,9 +41,29 @@
return LLVirtualList(self.T, items_a)
def build_runtime_container(self, builder):
+ rtyper = builder.interp.rtyper
+ LIST = self.T
+
+ argtypes = [lltype.Signed]
+ ll_newlist_ptr = rtyper.annotate_helper_fn(LIST.ll_newlist,
+ argtypes)
+ c_ll_newlist = rgenop.constPrebuiltGlobal(ll_newlist_ptr)
+ ll_newlist_sig = rgenop.sigToken(lltype.typeOf(ll_newlist_ptr).TO)
+
+ argtypes = [lltype.Ptr(LIST), lltype.Signed, LIST.ITEM]
+ ll_setitem_ptr = rtyper.annotate_helper_fn(LIST.ll_setitem_fast,
+ argtypes)
+ c_ll_setitem = rgenop.constPrebuiltGlobal(ll_setitem_ptr)
+ ll_setitem_sig = rgenop.sigToken(lltype.typeOf(ll_setitem_ptr).TO)
+
items_v = [a.forcegenvarorconst(builder) for a in self.items_a]
- v_result = self.T.list_builder.build(builder, items_v)
- return v_result
+ v_list = builder.genop_call(ll_newlist_sig, c_ll_newlist,
+ [None, builder.genconst(len(items_v))])
+
+ for i in range(len(items_v)):
+ builder.genop_call(ll_setitem_sig, c_ll_setitem,
+ [v_list, builder.genconst(i), items_v[i]])
+ return v_list
# ____________________________________________________________
# High-level operations
Modified: pypy/dist/pypy/jit/timeshifter/oop.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/oop.py (original)
+++ pypy/dist/pypy/jit/timeshifter/oop.py Sat Sep 2 20:30:29 2006
@@ -28,19 +28,20 @@
self.argpositions = []
for i, obj in enumerate(self.argtuple):
if isinstance(obj, Index):
- self.argpositions.append(obj.n + 1)
+ self.argpositions.append(obj.n)
else:
- self.argpositions.append(0)
+ self.argpositions.append(-1)
for i in range(nb_args):
ARGTYPE = FUNCTYPE.ARGS[i]
- assert ((i+1) in self.argpositions) == (ARGTYPE is not lltype.Void)
+ assert (i in self.argpositions) == (ARGTYPE is not lltype.Void)
RGenOp = hrtyper.RGenOp
self.args_gv = [None] * nb_args
- self.args_gv.insert(0, RGenOp.constPrebuiltGlobal(fnobj._as_ptr()))
+ self.gv_fnptr = RGenOp.constPrebuiltGlobal(fnobj._as_ptr())
self.result_kind = RGenOp.kindToken(FUNCTYPE.RESULT)
self.redboxbuilder = rvalue.ll_redboxbuilder(FUNCTYPE.RESULT)
+ self.sigtoken = RGenOp.sigToken(FUNCTYPE)
if operation_name == 'newlist':
from pypy.jit.timeshifter.vlist import ListTypeDesc, oop_newlist
@@ -58,10 +59,8 @@
argpositions = self.argpositions
for i in range(len(argpositions)):
pos = argpositions[i]
- if pos > 0:
+ if pos >= 0:
gv_arg = argboxes[i].getgenvar(builder)
args_gv[pos] = gv_arg
- gv_result = builder.genop('direct_call',
- args_gv,
- self.result_kind)
+ gv_result = builder.genop_call(self.sigtoken, self.gv_fnptr, args_gv)
return self.redboxbuilder(self.result_kind, gv_result)
Modified: pypy/dist/pypy/jit/timeshifter/rcontainer.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/rcontainer.py (original)
+++ pypy/dist/pypy/jit/timeshifter/rcontainer.py Sat Sep 2 20:30:29 2006
@@ -123,6 +123,7 @@
assert isinstance(PTRTYPE.TO, lltype.Array)
FieldDesc.__init__(self, RGenOp, PTRTYPE, PTRTYPE.TO.OF)
self.arraytoken = RGenOp.arrayToken(PTRTYPE.TO)
+ self.indexkind = RGenOp.kindToken(lltype.Signed)
# ____________________________________________________________
Modified: pypy/dist/pypy/jit/timeshifter/rtimeshift.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/rtimeshift.py (original)
+++ pypy/dist/pypy/jit/timeshifter/rtimeshift.py Sat Sep 2 20:30:29 2006
@@ -61,9 +61,8 @@
arg = rvalue.ll_getvalue(argbox, ARG0)
res = opdesc.llop(RESULT, arg)
return rvalue.ll_fromvalue(jitstate, res)
- op_args = [argbox.getgenvar(jitstate.curbuilder)]
- genvar = jitstate.curbuilder.genop(opdesc.opname, op_args,
- opdesc.result_kind)
+ gv_arg = argbox.getgenvar(jitstate.curbuilder)
+ genvar = jitstate.curbuilder.genop1(opdesc.opname, gv_arg)
return opdesc.redboxcls(opdesc.result_kind, genvar)
def ll_generate_operation2(opdesc, jitstate, argbox0, argbox1):
@@ -77,10 +76,9 @@
arg1 = rvalue.ll_getvalue(argbox1, ARG1)
res = opdesc.llop(RESULT, arg0, arg1)
return rvalue.ll_fromvalue(jitstate, res)
- op_args = [argbox0.getgenvar(jitstate.curbuilder),
- argbox1.getgenvar(jitstate.curbuilder)]
- genvar = jitstate.curbuilder.genop(opdesc.opname, op_args,
- opdesc.result_kind)
+ gv_arg0 = argbox0.getgenvar(jitstate.curbuilder)
+ gv_arg1 = argbox1.getgenvar(jitstate.curbuilder)
+ genvar = jitstate.curbuilder.genop2(opdesc.opname, gv_arg0, gv_arg1)
return opdesc.redboxcls(opdesc.result_kind, genvar)
def ll_generate_getfield(jitstate, fielddesc, argbox):
@@ -128,6 +126,16 @@
return fielddesc.redboxcls(fielddesc.kind, genvar)
+def ll_generate_getarraysize(jitstate, fielddesc, argbox):
+ if argbox.is_constant():
+ array = rvalue.ll_getvalue(argbox, fielddesc.PTRTYPE)
+ res = len(array)
+ return rvalue.ll_fromvalue(jitstate, res)
+ genvar = jitstate.curbuilder.genop_getarraysize(
+ fielddesc.arraytoken,
+ argbox.getgenvar(jitstate.curbuilder))
+ return rvalue.IntRedBox(fielddesc.indexkind, genvar)
+
# ____________________________________________________________
# other jitstate/graph level operations
@@ -299,9 +307,20 @@
## return self.rgenop.placeholder(dummy)
## genvoidconst._annspecialcase_ = 'specialize:arg(1)'
- def genop(self, opname, args_gv, result_kind=None):
- return self.block.genop(opname, args_gv, result_kind)
- genop._annspecialcase_ = 'specialize:arg(1)'
+## def genop(self, opname, args_gv, result_kind=None):
+## return self.block.genop(opname, args_gv, result_kind)
+## genop._annspecialcase_ = 'specialize:arg(1)'
+
+ def genop1(self, opname, gv_arg):
+ return self.block.genop1(opname, gv_arg)
+ genop1._annspecialcase_ = 'specialize:arg(1)'
+
+ def genop2(self, opname, gv_arg1, gv_arg2):
+ return self.block.genop2(opname, gv_arg1, gv_arg2)
+ genop2._annspecialcase_ = 'specialize:arg(1)'
+
+ def genop_call(self, sigtoken, gv_callable, args_gv):
+ return self.block.genop_call(sigtoken, gv_callable, args_gv)
def genop_getfield(self, fieldtoken, gv_ptr):
return self.block.genop_getfield(fieldtoken, gv_ptr)
@@ -314,10 +333,16 @@
def genop_getarrayitem(self, arraytoken, gv_ptr, gv_index):
return self.block.genop_getarrayitem(arraytoken, gv_ptr, gv_index)
+
+ def genop_getarraysize(self, arraytoken, gv_ptr):
+ return self.block.genop_getarraysize(arraytoken, gv_ptr)
def genop_malloc_fixedsize(self, alloctoken):
return self.block.genop_malloc_fixedsize(alloctoken)
+ def genop_same_as(self, kind, gv_value):
+ return self.block.genop_same_as(kind, gv_value)
+
def constTYPE(self, T):
return self.rgenop.constTYPE(T)
constTYPE._annspecialcase_ = 'specialize:arg(1)'
Modified: pypy/dist/pypy/jit/timeshifter/rtyper.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/rtyper.py (original)
+++ pypy/dist/pypy/jit/timeshifter/rtyper.py Sat Sep 2 20:30:29 2006
@@ -151,11 +151,32 @@
c_fielddesc = inputconst(lltype.Void, fielddesc)
s_fielddesc = ts.rtyper.annotator.bookkeeper.immutablevalue(fielddesc)
v_jitstate = hop.llops.getjitstate()
- return hop.llops.genmixlevelhelpercall(rtimeshift.ll_generate_getarrayitem,
+ return hop.llops.genmixlevelhelpercall(
+ rtimeshift.ll_generate_getarrayitem,
[ts.s_JITState, s_fielddesc, ts.s_RedBox, ts.s_RedBox],
[v_jitstate, c_fielddesc, v_argbox, v_index ],
ts.s_RedBox)
+ def translate_op_getarraysize(self, hop):
+ res = self.generic_translate_operation(hop, force=True)
+ if res is not None:
+ return res
+
+ PTRTYPE = originalconcretetype(hop.args_s[0])
+ ts = self.timeshifter
+ [v_argbox] = hop.inputargs(self.getredrepr(PTRTYPE))
+
+ fielddesc = rcontainer.ArrayFieldDesc(self.RGenOp, PTRTYPE)
+ c_fielddesc = inputconst(lltype.Void, fielddesc)
+ s_fielddesc = ts.rtyper.annotator.bookkeeper.immutablevalue(fielddesc)
+ v_jitstate = hop.llops.getjitstate()
+ return hop.llops.genmixlevelhelpercall(
+ rtimeshift.ll_generate_getarraysize,
+ [ts.s_JITState, s_fielddesc, ts.s_RedBox],
+ [v_jitstate, c_fielddesc, v_argbox ],
+ ts.s_RedBox)
+
+
def translate_op_setfield(self, hop):
if isinstance(hop.args_r[0], BlueRepr):
return hop.args_r[0].timeshift_setfield(hop)
Modified: pypy/dist/pypy/jit/timeshifter/rvalue.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/rvalue.py (original)
+++ pypy/dist/pypy/jit/timeshifter/rvalue.py Sat Sep 2 20:30:29 2006
@@ -49,7 +49,7 @@
if self.is_constant():
# cannot mutate constant boxes in-place
box = self.copy(memo)
- box.genvar = builder.genop("same_as", [self.genvar], self.kind)
+ box.genvar = builder.genop_same_as(self.kind, self.genvar)
return box
else:
# force virtual containers
Modified: pypy/dist/pypy/jit/timeshifter/test/test_timeshift.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/test/test_timeshift.py (original)
+++ pypy/dist/pypy/jit/timeshifter/test/test_timeshift.py Sat Sep 2 20:30:29 2006
@@ -151,22 +151,22 @@
llvalue = args[1]
args = args[2:]
TYPE = lltype.typeOf(llvalue)
- gv_type = rgenop.constTYPE(TYPE)
+ kind = rgenop.kindToken(TYPE)
boxcls = rvalue.ll_redboxcls(TYPE)
- gv_arg = rtimeshift.ll_geninputarg(builder, gv_type)
+ gv_arg = rtimeshift.ll_geninputarg(builder, kind)
if is_constant:
# ignore the gv_arg above, which is still present
# to give the residual graph a uniform signature
gv_arg = rgenop.genconst(llvalue)
- box = boxcls(gv_type, gv_arg)
+ box = boxcls(kind, gv_arg)
timeshifted_entrypoint_args += (box,)
startblock = rtimeshift.ll_end_setup_builder(builder)
endbuilder = timeshifted_entrypoint(builder, None,
*timeshifted_entrypoint_args)
endbuilder.finish_and_return()
- gv_functype = rgenop.constTYPE(FUNC)
- gv_generated = rgenop.gencallableconst("generated", startblock,
- gv_functype)
+ sigtoken = rgenop.sigToken(FUNC)
+ gv_generated = rgenop.gencallableconst(sigtoken, "generated",
+ startblock)
generated = gv_generated.revealconst(lltype.Ptr(FUNC))
return generated
Modified: pypy/dist/pypy/jit/timeshifter/vlist.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/vlist.py (original)
+++ pypy/dist/pypy/jit/timeshifter/vlist.py Sat Sep 2 20:30:29 2006
@@ -17,11 +17,14 @@
ll_newlist_ptr = rtyper.annotate_helper_fn(LIST.ll_newlist,
argtypes)
self.gv_ll_newlist = RGenOp.constPrebuiltGlobal(ll_newlist_ptr)
+ self.tok_ll_newlist = RGenOp.sigToken(lltype.typeOf(ll_newlist_ptr).TO)
argtypes = [self.LISTPTR, lltype.Signed, LIST.ITEM]
ll_setitem_fast = rtyper.annotate_helper_fn(LIST.ll_setitem_fast,
argtypes)
self.gv_ll_setitem_fast = RGenOp.constPrebuiltGlobal(ll_setitem_fast)
+ self.tok_ll_setitem_fast = RGenOp.sigToken(
+ lltype.typeOf(ll_setitem_fast).TO)
def factory(self, length, itembox):
vlist = VirtualList(self, length, itembox)
@@ -84,15 +87,18 @@
boxes = self.item_boxes
self.item_boxes = None
- args_gv = [typedesc.gv_ll_newlist, None, builder.genconst(len(boxes))]
- gv_list = builder.genop('direct_call', args_gv, typedesc.ptrkind)
+ args_gv = [None, builder.genconst(len(boxes))]
+ gv_list = builder.genop_call(typedesc.tok_ll_newlist,
+ typedesc.gv_ll_newlist,
+ args_gv)
self.ownbox.genvar = gv_list
self.ownbox.content = None
for i in range(len(boxes)):
gv_item = boxes[i].getgenvar(builder)
- args_gv = [typedesc.gv_ll_setitem_fast, gv_list,
- builder.genconst(i), gv_item]
- builder.genop('direct_call', args_gv)
+ args_gv = [gv_list, builder.genconst(i), gv_item]
+ builder.genop_call(typedesc.tok_ll_setitem_fast,
+ typedesc.gv_ll_setitem_fast,
+ args_gv)
def freeze(self, memo):
contmemo = memo.containers
Modified: pypy/dist/pypy/rpython/lltypesystem/lloperation.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/lloperation.py (original)
+++ pypy/dist/pypy/rpython/lltypesystem/lloperation.py Sat Sep 2 20:30:29 2006
@@ -3,6 +3,7 @@
"""
from pypy.rpython.extregistry import ExtRegistryEntry
+from pypy.objspace.flow.model import roproperty
class LLOp(object):
@@ -54,7 +55,7 @@
val = lltype.enforce(RESULTTYPE, val)
return val
- def fold(self, RESULTTYPE, *args):
+ def get_fold_impl(self):
global lltype # <- lazy import hack, worth an XXX
from pypy.rpython.lltypesystem import lltype
if self.canfold or self.opname in ('getfield', 'getarrayitem'):
@@ -67,8 +68,8 @@
raise error
# cache the implementation function into 'self'
self.fold = op_impl
- return self(RESULTTYPE, *args)
- fold.need_result_type = True
+ return op_impl
+ fold = roproperty(get_fold_impl)
def enum_ops_without_sideeffects(raising_is_ok=False):
More information about the Pypy-commit
mailing list