Author: Richard Plangger <r...@pasra.at>
Branch: vecopt2
Changeset: r77131:ce46889cad5d
Date: 2015-05-04 15:16 +0200
http://bitbucket.org/pypy/pypy/changeset/ce46889cad5d/

Log:    bridge can now be assembled (previously an early exit skipped to the
        blackhole interpreter) added a test case to test a vector that is
        too small

diff --git a/rpython/jit/metainterp/compile.py 
b/rpython/jit/metainterp/compile.py
--- a/rpython/jit/metainterp/compile.py
+++ b/rpython/jit/metainterp/compile.py
@@ -836,13 +836,14 @@
     new_trace.operations = metainterp.history.operations[:]
     metainterp_sd = metainterp.staticdata
     jitdriver_sd = metainterp.jitdriver_sd
-    state = jitdriver_sd.warmstate
-    if isinstance(resumekey, ResumeAtPositionDescr):
+    warmstate = jitdriver_sd.warmstate
+    if isinstance(resumekey, ResumeAtPositionDescr) or \
+       isinstance(resumekey, ResumeAtLoopHeaderDescr):
         inline_short_preamble = False
     else:
         inline_short_preamble = True
     try:
-        state = optimize_trace(metainterp_sd, jitdriver_sd, new_trace, state,
+        state = optimize_trace(metainterp_sd, jitdriver_sd, new_trace, 
warmstate,
                                inline_short_preamble, export_state=True)
     except InvalidLoop:
         debug_print("compile_new_bridge: got an InvalidLoop")
diff --git a/rpython/jit/metainterp/optimizeopt/__init__.py 
b/rpython/jit/metainterp/optimizeopt/__init__.py
--- a/rpython/jit/metainterp/optimizeopt/__init__.py
+++ b/rpython/jit/metainterp/optimizeopt/__init__.py
@@ -69,7 +69,8 @@
         optimizations, unroll = build_opt_chain(metainterp_sd, enable_opts)
         if unroll:
             if not export_state and warmstate.vectorize and 
jitdriver_sd.vectorize:
-                optimize_vector(metainterp_sd, jitdriver_sd, loop, 
optimizations)
+                optimize_vector(metainterp_sd, jitdriver_sd, loop, 
optimizations,
+                                inline_short_preamble, start_state)
             else:
                 return optimize_unroll(metainterp_sd, jitdriver_sd, loop,
                                        optimizations, inline_short_preamble,
diff --git a/rpython/jit/metainterp/optimizeopt/dependency.py 
b/rpython/jit/metainterp/optimizeopt/dependency.py
--- a/rpython/jit/metainterp/optimizeopt/dependency.py
+++ b/rpython/jit/metainterp/optimizeopt/dependency.py
@@ -116,13 +116,19 @@
         op = guard.getoperation()
         assert isinstance(tgt_op, GuardResOp)
         assert isinstance(op, GuardResOp)
-        #descr = compile.ResumeAtLoopHeaderDescr()
+        olddescr = tgt_op.getdescr()
         descr = compile.ResumeAtLoopHeaderDescr()
+        descr.rd_consts = olddescr.rd_consts 
+        descr.rd_pendingfields = olddescr.rd_pendingfields
+        descr.rd_virtuals = olddescr.rd_virtuals
+        descr.rd_numb = olddescr.rd_numb
+        descr.rd_count = olddescr.rd_count
+        descr.rd_frame_info_list = olddescr.rd_frame_info_list
+        #
         tgt_op.setdescr(descr)
-        if not we_are_translated():
-            tgt_op.setfailargs(op.getfailargs())
         tgt_op.rd_snapshot = op.rd_snapshot
-        tgt_op.rd_frame_info_list = op.rd_frame_info_list
+        #if not we_are_translated():
+        tgt_op.setfailargs(op.getfailargs())
 
     def edge_to(self, to, arg=None, label=None):
         assert self != to
@@ -360,12 +366,14 @@
         self.defs = {}
 
     def define(self, arg, node, argcell=None):
+        if isinstance(arg, Const):
+            return
         if arg in self.defs:
             self.defs[arg].append((node,argcell))
         else:
             self.defs[arg] = [(node,argcell)]
 
-    def redefintions(self, arg):
+    def redefinitions(self, arg):
         for _def in self.defs[arg]:
             yield _def[0]
 
@@ -424,8 +432,9 @@
         modifications of one array even if the indices can never point to
         the same element.
     """
-    def __init__(self, operations):
-        self.nodes = [ Node(op,i) for i,op in enumerate(operations) ]
+    def __init__(self, loop):
+        self.loop = loop
+        self.nodes = [ Node(op,i) for i,op in enumerate(loop.operations) ]
         self.memory_refs = {}
         self.schedulable_nodes = []
         self.index_vars = {}
@@ -455,14 +464,16 @@
             # the label operation defines all operations at the
             # beginning of the loop
             if op.getopnum() == rop.LABEL and i != jump_pos:
-                # TODO is it valid that a label occurs at the end of a trace?
-                ee_node = self.nodes[i+1]
-                if ee_node.is_guard_early_exit():
-                    node.edge_to(ee_node,None,label='L->EE')
-                    node = ee_node
+                label_pos = i
                 for arg in op.getarglist():
                     tracker.define(arg, node)
                 continue # prevent adding edge to the label itself
+            elif node.is_guard_early_exit():
+                label_node = self.nodes[label_pos]
+                label_node.edge_to(node,None,label='L->EE')
+                for arg in label_node.getoperation().getarglist():
+                    tracker.define(arg, node)
+                continue
             intformod.inspect_operation(op,node)
             # definition of a new variable
             if op.result is not None:
@@ -529,9 +540,11 @@
         if guard_op.getfailargs():
             for arg in guard_op.getfailargs():
                 try:
-                    for at in tracker.redefintions(arg):
+                    for at in tracker.redefinitions(arg):
                         # later redefinitions are prohibited
-                        if at.is_before(guard_node):
+                        descr = guard_op.getdescr()
+                        if at.is_before(guard_node) and \
+                           not isinstance(descr, 
compile.ResumeAtLoopHeaderDescr):
                             at.edge_to(guard_node, arg, label="fail")
                 except KeyError:
                     assert False
@@ -619,7 +632,7 @@
                 op = node.getoperation()
                 op_str = str(op)
                 if op.is_guard():
-                    op_str += " " + str(op.getfailargs())
+                    op_str += " " + ','.join([str(arg) for arg in 
op.getfailargs()])
                 dot += " n%d [label=\"[%d]: %s\"];\n" % 
(node.getindex(),node.getindex(),op_str)
             dot += "\n"
             for node in self.nodes:
diff --git a/rpython/jit/metainterp/optimizeopt/rewrite.py 
b/rpython/jit/metainterp/optimizeopt/rewrite.py
--- a/rpython/jit/metainterp/optimizeopt/rewrite.py
+++ b/rpython/jit/metainterp/optimizeopt/rewrite.py
@@ -559,9 +559,6 @@
     def optimize_GUARD_FUTURE_CONDITION(self, op):
         pass # just remove it
 
-    def optimize_GUARD_EARLY_EXIT(self, op):
-        pass # just remove it
-
     def optimize_INT_FLOORDIV(self, op):
         v1 = self.getvalue(op.getarg(0))
         v2 = self.getvalue(op.getarg(1))
diff --git a/rpython/jit/metainterp/optimizeopt/simplify.py 
b/rpython/jit/metainterp/optimizeopt/simplify.py
--- a/rpython/jit/metainterp/optimizeopt/simplify.py
+++ b/rpython/jit/metainterp/optimizeopt/simplify.py
@@ -65,9 +65,6 @@
     def optimize_GUARD_FUTURE_CONDITION(self, op):
         pass
 
-    def optimize_GUARD_EARLY_EXIT(self, op):
-        pass
-
 dispatch_opt = make_dispatcher_method(OptSimplify, 'optimize_',
         default=OptSimplify.emit_operation)
 OptSimplify.propagate_forward = dispatch_opt
diff --git a/rpython/jit/metainterp/optimizeopt/test/test_dependency.py 
b/rpython/jit/metainterp/optimizeopt/test/test_dependency.py
--- a/rpython/jit/metainterp/optimizeopt/test/test_dependency.py
+++ b/rpython/jit/metainterp/optimizeopt/test/test_dependency.py
@@ -15,7 +15,7 @@
 
     def build_dependency(self, ops):
         loop = self.parse_loop(ops)
-        self.last_graph = DependencyGraph(loop.operations)
+        self.last_graph = DependencyGraph(loop)
         self._write_dot_and_convert_to_svg(self.last_graph, self.test_name)
         for node in self.last_graph.nodes:
             assert node.independent(node)
diff --git a/rpython/jit/metainterp/optimizeopt/vectorize.py 
b/rpython/jit/metainterp/optimizeopt/vectorize.py
--- a/rpython/jit/metainterp/optimizeopt/vectorize.py
+++ b/rpython/jit/metainterp/optimizeopt/vectorize.py
@@ -1,7 +1,9 @@
-import sys
 import py
+
+from rpython.jit.metainterp.resume import Snapshot
+from rpython.jit.metainterp.jitexc import JitException
+from rpython.jit.metainterp.optimizeopt.unroll import optimize_unroll
 from rpython.jit.metainterp.compile import ResumeAtLoopHeaderDescr
-from rpython.rtyper.lltypesystem import lltype, rffi
 from rpython.jit.metainterp.history import (ConstInt, VECTOR, BoxVector,
         TargetToken, JitCellToken)
 from rpython.jit.metainterp.optimizeopt.optimizer import Optimizer, 
Optimization
@@ -9,10 +11,9 @@
 from rpython.jit.metainterp.optimizeopt.dependency import (DependencyGraph, 
         MemoryRef, Scheduler, SchedulerData, Node)
 from rpython.jit.metainterp.resoperation import (rop, ResOperation, GuardResOp)
-from rpython.jit.metainterp.resume import Snapshot
+from rpython.rlib.objectmodel import we_are_translated
 from rpython.rlib.debug import debug_print, debug_start, debug_stop
-from rpython.jit.metainterp.jitexc import JitException
-from rpython.rlib.objectmodel import we_are_translated
+from rpython.rtyper.lltypesystem import lltype, rffi
 
 class NotAVectorizeableLoop(JitException):
     def __str__(self):
@@ -41,17 +42,16 @@
             else:
                 print ""
 
-def optimize_vector(metainterp_sd, jitdriver_sd, loop, optimizations):
-    opt = VectorizingOptimizer(metainterp_sd, jitdriver_sd, loop, 
optimizations)
+def optimize_vector(metainterp_sd, jitdriver_sd, loop, optimizations,
+                    inline_short_preamble, start_state):
+    optimize_unroll(metainterp_sd, jitdriver_sd, loop, optimizations,
+                    inline_short_preamble, start_state, False)
     try:
+        opt = VectorizingOptimizer(metainterp_sd, jitdriver_sd, loop, 
optimizations)
         opt.propagate_all_forward()
-        #debug_print_operations(loop)
-        def_opt = Optimizer(metainterp_sd, jitdriver_sd, loop, optimizations)
-        def_opt.propagate_all_forward()
     except NotAVectorizeableLoop:
         # vectorization is not possible, propagate only normal optimizations
-        def_opt = Optimizer(metainterp_sd, jitdriver_sd, loop, optimizations)
-        def_opt.propagate_all_forward()
+        pass
 
 #class CollapseGuardOptimization(Optimization):
 #    def __init__(self, index_vars = None):
@@ -99,6 +99,7 @@
         self.loop.operations = self.get_newoperations();
         self.clear_newoperations();
 
+        debug_print_operations(self.loop)
         # vectorize
         self.build_dependency_graph()
         self.find_adjacent_memory_refs()
@@ -265,7 +266,7 @@
         return unroll_count-1 # it is already unrolled once
 
     def build_dependency_graph(self):
-        self.dependency_graph = DependencyGraph(self.loop.operations)
+        self.dependency_graph = DependencyGraph(self.loop)
 
     def find_adjacent_memory_refs(self):
         """ the pre pass already builds a hash of memory references and the
@@ -390,7 +391,7 @@
         if len(self.loop.operations) <= 1 or self.early_exit_idx == -1:
             return
 
-        self.dependency_graph = dependencies = 
DependencyGraph(self.loop.operations)
+        self.dependency_graph = dependencies = DependencyGraph(self.loop)
 
         label_node = dependencies.getnode(0)
         ee_guard_node = dependencies.getnode(self.early_exit_idx)
diff --git a/rpython/jit/metainterp/pyjitpl.py 
b/rpython/jit/metainterp/pyjitpl.py
--- a/rpython/jit/metainterp/pyjitpl.py
+++ b/rpython/jit/metainterp/pyjitpl.py
@@ -1122,6 +1122,8 @@
 
         if self.metainterp.seen_loop_header_for_jdindex < 0:
             if not any_operation:
+                if jitdriver_sd.vectorize:
+                    self.metainterp.generate_guard(rop.GUARD_EARLY_EXIT)
                 return
             if self.metainterp.portal_call_depth or not 
self.metainterp.get_procedure_token(greenboxes, True):
                 if not jitdriver_sd.no_loop_header:
@@ -2133,12 +2135,6 @@
         self.resumekey = compile.ResumeFromInterpDescr(original_greenkey)
         self.history.inputargs = original_boxes[num_green_args:]
         self.seen_loop_header_for_jdindex = -1
-        # can only emit early exit if liveness is present
-        # TODO think of a better way later
-        if self.framestack[-1].jitcode.liveness.get(0, None) \
-           and self.jitdriver_sd.vectorize:
-            self.generate_guard(rop.GUARD_EARLY_EXIT)
-            #self.history.record(rop.GUARD_EARLY_EXIT, [], None)
         try:
             self.interpret()
         except SwitchToBlackhole, stb:
@@ -2318,9 +2314,7 @@
         if opnum == rop.GUARD_FUTURE_CONDITION:
             pass
         elif opnum == rop.GUARD_EARLY_EXIT:
-            # prevents it from building a bridge
-            # TODO
-            self.resumekey_original_loop_token = None
+            pass
         elif opnum == rop.GUARD_TRUE:     # a goto_if_not that jumps only now
             frame.pc = frame.jitcode.follow_jump(frame.pc)
         elif opnum == rop.GUARD_FALSE:     # a goto_if_not that stops jumping;
diff --git a/rpython/jit/metainterp/test/test_vectorize.py 
b/rpython/jit/metainterp/test/test_vectorize.py
--- a/rpython/jit/metainterp/test/test_vectorize.py
+++ b/rpython/jit/metainterp/test/test_vectorize.py
@@ -28,7 +28,7 @@
     @py.test.mark.parametrize('i',[3,4,5,6,7,8,9,50])
     def test_vectorize_simple_load_arith_store_int_add_index(self,i):
         myjitdriver = JitDriver(greens = [],
-                                reds = ['i','d','bc','va','vb','vc'],
+                                reds = 'auto',
                                 vectorize=True)
         def f(d):
             bc = d*rffi.sizeof(rffi.SIGNED)
@@ -42,8 +42,7 @@
                 raw_storage_setitem(vb, j, rffi.cast(rffi.SIGNED,i))
             i = 0
             while i < bc:
-                myjitdriver.can_enter_jit(i=i, d=d, va=va, vb=vb, vc=vc, bc=bc)
-                myjitdriver.jit_merge_point(i=i, d=d, va=va, vb=vb, vc=vc, 
bc=bc)
+                myjitdriver.jit_merge_point()
                 a = raw_storage_getitem(rffi.SIGNED,va,i)
                 b = raw_storage_getitem(rffi.SIGNED,vb,i)
                 c = a+b
@@ -62,7 +61,7 @@
         if i > 3:
             self.check_trace_count(1)
 
-    @py.test.mark.parametrize('i',[1,2,3,8,17,128,500,501,502,1300])
+    @py.test.mark.parametrize('i',[1,2,3,8,17,128,130,500,501,502,1300])
     def test_vectorize_array_get_set(self,i):
         myjitdriver = JitDriver(greens = [],
                                 reds = ['i','d','va','vb','vc'],
@@ -95,8 +94,40 @@
             return res
         res = self.meta_interp(f, [i])
         assert res == f(i)
-        if 4 < i:
-            self.check_trace_count(1)
+        #if 4 < i:
+        #    self.check_trace_count(1)
+
+    @py.test.mark.parametrize('i,k',[(9,3)])
+    def test_vector_register_too_small_vector(self, i, k):
+        myjitdriver = JitDriver(greens = [],
+                                reds = 'auto',
+                                vectorize=True)
+        T = lltype.Array(rffi.SHORT, hints={'nolength': True})
+        def f(d,v):
+            i = 0
+            va = lltype.malloc(T, v, flavor='raw', zero=True)
+            vb = lltype.malloc(T, v, flavor='raw', zero=True)
+            for j in range(v):
+                va[j] = rffi.r_short(1)
+                vb[j] = rffi.r_short(2)
+            while i < d:
+                myjitdriver.jit_merge_point()
+                j = 0
+                while j < v:
+                    a = va[j]
+                    b = vb[j]
+                    ec = intmask(a) + intmask(b)
+                    va[j] = rffi.r_short(ec)
+                    j += 1
+
+                i += 1
+            res = intmask(va[v-1])
+            lltype.free(va, flavor='raw')
+            lltype.free(vb, flavor='raw')
+            return res
+        res = self.meta_interp(f, [i,k])
+        assert res == f(i,k)
+
 
 class VectorizeLLtypeTests(VectorizeTests):
     pass
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to