[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