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