[pypy-svn] r20974 - in pypy/dist/pypy/jit: . test
arigo at codespeak.net
arigo at codespeak.net
Fri Dec 9 20:55:59 CET 2005
Author: arigo
Date: Fri Dec 9 20:55:55 2005
New Revision: 20974
Modified:
pypy/dist/pypy/jit/llabstractinterp.py
pypy/dist/pypy/jit/test/test_jit_tl.py
pypy/dist/pypy/jit/test/test_llabstractinterp.py
pypy/dist/pypy/jit/test/test_tl.py
pypy/dist/pypy/jit/tl.py
pypy/dist/pypy/jit/tlopcode.py
Log:
(mwh, arigo)
* Changed the Toy Language CALL/RETURN to use recursive calls.
* Implemented some more operations, fixed bugs.
* Added tests.
Modified: pypy/dist/pypy/jit/llabstractinterp.py
==============================================================================
--- pypy/dist/pypy/jit/llabstractinterp.py (original)
+++ pypy/dist/pypy/jit/llabstractinterp.py Fri Dec 9 20:55:55 2005
@@ -92,10 +92,10 @@
class GraphState(object):
"""Entry state of a graph."""
- def __init__(self, origgraph, args_a):
- super(GraphState, self).__init__(args_a)
+ def __init__(self, origgraph, args_a, n):
self.origgraph = origgraph
- self.copygraph = FunctionGraph(origgraph.name, Block([])) # grumble
+ name = '%s_%d' % (origgraph.name, n)
+ self.copygraph = FunctionGraph(name, Block([])) # grumble
for orig_v, copy_v in [(origgraph.getreturnvar(),
self.copygraph.getreturnvar()),
(origgraph.exceptblock.inputargs[0],
@@ -114,6 +114,7 @@
def complete(self, interp):
assert self.state != "during"
if self.state == "before":
+ self.state = "during"
builderframe = LLAbstractFrame(interp, self)
builderframe.complete()
self.state = "after"
@@ -157,8 +158,8 @@
try:
graphstate = self.graphs[origgraph][state]
except KeyError:
- graphstate = GraphState(origgraph, args_a)
d = self.graphs.setdefault(origgraph, {})
+ graphstate = GraphState(origgraph, args_a, n=len(d))
d[state] = graphstate
self.pendingstates[graphstate] = state
#print "SCHEDULE_GRAPH", graphstate
@@ -284,7 +285,6 @@
if len(origblock.inputargs) == 1:
target = self.graphstate.copygraph.returnblock
else:
- XXX_later
target = self.graphstate.copygraph.exceptblock
args_v = [binding(v).getvarorconst() for v in origblock.inputargs]
newlinks = [Link(args_v, target)]
@@ -388,14 +388,18 @@
v_func = a_func.getvarorconst()
if isinstance(v_func, Constant):
fnobj = v_func.value._obj
- if hasattr(fnobj, 'graph'):
+ if (hasattr(fnobj, 'graph') and
+ not getattr(fnobj._callable, 'suggested_primitive', False)):
origgraph = fnobj.graph
graphstate, args_a = self.interp.schedule_graph(
args_a, origgraph)
+ #print 'SCHEDULE_GRAPH', args_a, '==>', graphstate.copygraph.name
if graphstate.state != "during":
print 'ENTERING', graphstate.copygraph.name, args_a
graphstate.complete(self.interp)
- if isinstance(graphstate.a_return, LLConcreteValue):
+ if (graphstate.a_return is not None and
+ isinstance(graphstate.a_return.getvarorconst(),
+ Constant)):
a_result = graphstate.a_return
print 'LEAVING', graphstate.copygraph.name, graphstate.a_return
@@ -410,11 +414,11 @@
TYPE = lltype.FuncType(
ARGS, lltype.typeOf(origfptr).TO.RESULT)
fptr = lltype.functionptr(
- TYPE, fnobj._name, graph=graphstate.copygraph)
+ TYPE, graphstate.copygraph.name, graph=graphstate.copygraph)
fconst = Constant(fptr)
fconst.concretetype = lltype.typeOf(fptr)
a_func = LLRuntimeValue(fconst)
- self.residual("direct_call", [a_func] + args_a, a_result)
+ self.residual("direct_call", [a_func] + list(args_a), a_result)
return a_result
def op_getfield(self, op, a_ptr, a_attrname):
@@ -448,3 +452,8 @@
def op_setarrayitem(self, op, a_ptr, a_index, a_value):
return self.residualize(op, [a_ptr, a_index, a_value])
+
+ def op_cast_pointer(self, op, a_ptr):
+ def constant_op(ptr):
+ return lltype.cast_pointer(op.result.concretetype, ptr)
+ return self.residualize(op, [a_ptr], constant_op)
Modified: pypy/dist/pypy/jit/test/test_jit_tl.py
==============================================================================
--- pypy/dist/pypy/jit/test/test_jit_tl.py (original)
+++ pypy/dist/pypy/jit/test/test_jit_tl.py Fri Dec 9 20:55:55 2005
@@ -6,9 +6,14 @@
from pypy.rpython.rstr import string_repr
from pypy.rpython.llinterp import LLInterpreter
+def entry_point(code, pc):
+ # indirection needed, because the hints are not about *all* calls to
+ # interp()
+ return tl.interp(code, pc)
+
def jit_tl(code):
t = TranslationContext()
- t.buildannotator().build_types(tl.interp, [str, int])
+ t.buildannotator().build_types(entry_point, [str, int])
rtyper = t.buildrtyper()
rtyper.specialize()
graph1 = t.graphs[0]
@@ -31,12 +36,54 @@
jit_tl(code)
-def test_jit_tl_1():
- for code in [
- ''' PUSH 42
- ''',
- ''' PUSH 6
- PUSH 7
+def test_simple1():
+ run_jit(''' PUSH 42
+ ''')
+
+def test_simple2():
+ run_jit(''' PUSH 6
+ PUSH 7
+ ADD
+ ''')
+
+def test_branches():
+ run_jit('''
+ main:
+ PUSH 0
+ PUSH 1
+ BR_COND somename
+ label1:
+ PUSH -1
+ PUSH 3
+ BR_COND end
+ somename: ;
+ PUSH 2 //
+ BR_COND label1//
+ end:// should return 3
+ ''')
+
+def test_exceptions():
+ run_jit('''
+ PUSH 42
+ PUSH -42
+ ROT 2 # at the moment we see a potential IndexError here
+ ''')
+
+def test_calls():
+ run_jit('''
+ PUSH 1
+ CALL func1
+ PUSH 3
+ CALL func2
+ RETURN
+
+ func1:
+ PUSH 2
+ RETURN # comment
+
+ func2:
+ PUSH 4 ;comment
+ PUSH 5
ADD
- ''']:
- yield run_jit, code
+ RETURN
+ ''')
Modified: pypy/dist/pypy/jit/test/test_llabstractinterp.py
==============================================================================
--- pypy/dist/pypy/jit/test/test_llabstractinterp.py (original)
+++ pypy/dist/pypy/jit/test/test_llabstractinterp.py Fri Dec 9 20:55:55 2005
@@ -169,3 +169,16 @@
graph2, insns = abstrinterp(ll_function, [s, 0, 0], [0, 1, 2])
assert insns == {}
+def test_recursive_call():
+ def ll_factorial(k):
+ if k <= 1:
+ return 1
+ else:
+ return ll_factorial(k-1) * k
+ def ll_function(k):
+ # indirection needed, because the hint is not about *all* calls to
+ # ll_factorial()
+ return ll_factorial(k)
+ graph2, insns = abstrinterp(ll_function, [7], [0])
+ # the direct_calls are messy to count, with calls to ll_stack_check
+ assert insns.keys() == ['direct_call']
Modified: pypy/dist/pypy/jit/test/test_tl.py
==============================================================================
--- pypy/dist/pypy/jit/test/test_tl.py (original)
+++ pypy/dist/pypy/jit/test/test_tl.py Fri Dec 9 20:55:55 2005
@@ -108,9 +108,9 @@
def test_branch0():
assert interp(list2bytecode([PUSH,7, PUSH,1, BR_COND,0])) == 7
-def test_exit():
- assert py.test.raises(IndexError, interp, list2bytecode([EXIT]))
- assert interp(list2bytecode([PUSH,7, EXIT, PUSH,5])) == 7
+def test_return():
+ assert py.test.raises(IndexError, interp, list2bytecode([RETURN]))
+ assert interp(list2bytecode([PUSH,7, RETURN, PUSH,5])) == 7
def test_rot():
code = [PUSH,1, PUSH,2, PUSH,3, ROT,3]
@@ -121,10 +121,8 @@
py.test.raises(IndexError, interp, list2bytecode([PUSH,1, PUSH,2, PUSH,3, ROT,4]))
def test_call_ret():
- assert py.test.raises(IndexError, interp, list2bytecode([RETURN]))
- assert interp(list2bytecode([PUSH,6, RETURN, PUSH,4, EXIT, PUSH,9])) == 9
- assert interp(list2bytecode([CALL,0])) == 2
- assert interp(list2bytecode([PUSH,1, CALL,5, PUSH,2, CALL,2, EXIT, RETURN, ROT,3, ADD, SWAP, RETURN])) == 3
+ assert interp(list2bytecode([CALL,1, RETURN, PUSH,2])) == 2
+ assert interp(list2bytecode([PUSH,6, CALL,2, MUL, RETURN, PUSH,7, RETURN])) == 42
def test_compile_branch_backwards():
code = compile("""
@@ -149,16 +147,19 @@
def test_compile_call_ret():
code = compile("""PUSH 1
CALL func1
- PUSH 2
+ PUSH 3
CALL func2
- EXIT
+ RETURN
func1:
+ PUSH 2
RETURN # comment
func2:
- ROT 3 ;comment
- ADD
- SWAP
+ PUSH 4 ;comment
+ PUSH 5
+ ADD
RETURN""")
- assert code == list2bytecode([PUSH,1, CALL,5, PUSH,2, CALL,2, EXIT, RETURN, ROT,3, ADD, SWAP, RETURN])
+ assert code == list2bytecode([PUSH,1, CALL,5, PUSH,3, CALL,4, RETURN,
+ PUSH,2, RETURN,
+ PUSH,4, PUSH,5, ADD, RETURN])
Modified: pypy/dist/pypy/jit/tl.py
==============================================================================
--- pypy/dist/pypy/jit/tl.py (original)
+++ pypy/dist/pypy/jit/tl.py Fri Dec 9 20:55:55 2005
@@ -96,13 +96,12 @@
pc += 1
elif opcode == CALL:
- stack.append( pc+1 )
- pc += char2int(code[pc]) + 1
+ offset = char2int(code[pc])
+ pc += 1
+ res = interp(code, pc + offset)
+ stack.append( res )
elif opcode == RETURN:
- pc = stack.pop()
-
- elif opcode == EXIT:
break
else:
Modified: pypy/dist/pypy/jit/tlopcode.py
==============================================================================
--- pypy/dist/pypy/jit/tlopcode.py (original)
+++ pypy/dist/pypy/jit/tlopcode.py Fri Dec 9 20:55:55 2005
@@ -31,8 +31,6 @@
opcode("CALL") #1 operand offset
opcode("RETURN")
-opcode("EXIT")
-
opcode("INVALID")
del opcode
More information about the Pypy-commit
mailing list