Author: Richard Plangger <r...@pasra.at> Branch: vecopt-merge Changeset: r79156:caedfb3ee99b Date: 2015-08-23 15:14 +0200 http://bitbucket.org/pypy/pypy/changeset/caedfb3ee99b/
Log: saving of accum state more explicit diff --git a/rpython/jit/backend/llsupport/assembler.py b/rpython/jit/backend/llsupport/assembler.py --- a/rpython/jit/backend/llsupport/assembler.py +++ b/rpython/jit/backend/llsupport/assembler.py @@ -3,7 +3,7 @@ from rpython.jit.backend.llsupport.symbolic import WORD from rpython.jit.backend.llsupport.codemap import CodemapBuilder from rpython.jit.metainterp.history import (INT, REF, FLOAT, VECTOR, - JitCellToken, ConstInt, BoxInt, AbstractFailDescr) + JitCellToken, ConstInt, BoxInt, AbstractFailDescr, BoxVector) from rpython.jit.metainterp.resoperation import ResOperation, rop from rpython.rlib import rgc from rpython.rlib.debug import (debug_start, debug_stop, have_debug_prints_for, diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py --- a/rpython/jit/backend/x86/assembler.py +++ b/rpython/jit/backend/x86/assembler.py @@ -10,7 +10,6 @@ from rpython.jit.metainterp.history import (Const, Box, VOID, BoxVector, ConstInt) from rpython.jit.metainterp.history import AbstractFailDescr, INT, REF, FLOAT -from rpython.jit.metainterp.compile import CompileLoopVersionDescr from rpython.rtyper.lltypesystem import lltype, rffi, rstr, llmemory from rpython.rtyper.lltypesystem.lloperation import llop from rpython.rtyper.annlowlevel import llhelper, cast_instance_to_gcref @@ -600,12 +599,12 @@ # at the end of self.mc. for tok in self.pending_guard_tokens: descr = tok.faildescr - if not isinstance(descr, CompileLoopVersionDescr): + if descr.loop_version(): + startpos = self.mc.get_relative_pos() + self.store_info_on_descr(startpos, tok) + else: regalloc.position = tok.position tok.pos_recovery_stub = self.generate_quick_failure(tok, regalloc) - else: - startpos = self.mc.get_relative_pos() - self.store_info_on_descr(startpos, tok) if WORD == 8 and len(self.pending_memoryerror_trampoline_from) > 0: self.error_trampoline_64 = self.generate_propagate_error_64() diff --git a/rpython/jit/backend/x86/regalloc.py b/rpython/jit/backend/x86/regalloc.py --- a/rpython/jit/backend/x86/regalloc.py +++ b/rpython/jit/backend/x86/regalloc.py @@ -27,6 +27,7 @@ FLOAT, VECTOR, TargetToken) from rpython.jit.metainterp.resoperation import rop, ResOperation from rpython.jit.metainterp.compile import ResumeGuardDescr +from rpython.jit.metainterp.resume import AccumInfo from rpython.rlib import rgc from rpython.rlib.objectmodel import we_are_translated from rpython.rlib.rarithmetic import r_longlong, r_uint @@ -320,37 +321,20 @@ continue accum = arg.getaccum() if accum: + # for an accumulator store the position of the original + # box and in llsupport/assembler save restore information + # on the descriptor loc = self.loc(accum.getoriginalbox()) faillocs.append(loc) - self.update_accumulation_loc(arg, accum, descr, i) + descr.rd_accum_list = AccumInfo(descr.rd_accum_list, + i, accum.operator, + accum.getoriginalbox(), + self.loc(arg)) else: faillocs.append(self.loc(arg)) return faillocs - def update_accumulation_loc(self, arg, accum, descr, pos): - """ - Faillocs saved on the guard can only represent one value. - Accumulation has the accumulation box which need to updated uppon - guard exit. The fail descr saves where (regloc) the accumulator - is located. - """ - assert isinstance(descr, ResumeGuardDescr) - accum_info = descr.rd_accum_list - count = 0 - while accum_info: - if accum_info.box is accum.getoriginalbox(): - accum_info.loc = self.loc(arg) - accum_info.position = pos - break - count += 1 - accum_info = accum_info.prev - else: - msg = "[accumulator] %d accumulators, none matched box %s" % (count, accum_info.box) - print msg - import pdb; pdb.set_trace() - not_implemented(msg) - def perform_with_guard(self, op, guard_op, arglocs, result_loc): faillocs = self.locs_for_fail(guard_op) self.rm.position += 1 diff --git a/rpython/jit/backend/x86/vector_ext.py b/rpython/jit/backend/x86/vector_ext.py --- a/rpython/jit/backend/x86/vector_ext.py +++ b/rpython/jit/backend/x86/vector_ext.py @@ -84,19 +84,19 @@ assert regalloc is not None accum_info = faildescr.rd_accum_list while accum_info: - pos = accum_info.position - loc = accum_info.loc - tgtloc = fail_locs[pos] + pos = accum_info.scalar_position + scalar_loc = fail_locs[pos] + vector_loc = accum_info.vector_loc # the upper elements will be lost if saved to the stack! - assert isinstance(loc, RegLoc) - if not isinstance(tgtloc, RegLoc): - tgtloc = regalloc.force_allocate_reg(accum_info.box) - arg = accum_info.box - assert arg is not None - if accum_info.operation == '+': - self._accum_reduce_sum(arg, loc, tgtloc) - elif accum_info.operation == '*': - self._accum_reduce_mul(arg, loc, tgtloc) + scalar_arg = accum_info.scalar_box + assert isinstance(vector_loc, RegLoc) + if not isinstance(scalar_loc, RegLoc): + scalar_loc = regalloc.force_allocate_reg(scalar_arg) + assert scalar_arg is not None + if accum_info.accum_operation == '+': + self._accum_reduce_sum(scalar_arg, vector_loc, scalar_loc) + elif accum_info.accum_operation == '*': + self._accum_reduce_mul(scalar_arg, vector_loc, scalar_loc) else: not_implemented("accum operator %s not implemented" % (accum_info.operation)) diff --git a/rpython/jit/metainterp/history.py b/rpython/jit/metainterp/history.py --- a/rpython/jit/metainterp/history.py +++ b/rpython/jit/metainterp/history.py @@ -550,13 +550,6 @@ def accumulates_value(self): return True - def save_to_descr(self, descr, position): - from rpython.jit.metainterp.compile import ResumeGuardDescr - from rpython.jit.metainterp.resume import AccumInfo - assert isinstance(descr, ResumeGuardDescr) - ai = AccumInfo(descr.rd_accum_list, position, self.operator, self.var) - descr.rd_accum_list = ai - class BoxVector(Box): type = VECTOR _attrs_ = ('item_type','item_count','item_size','item_signed','accum') @@ -819,7 +812,7 @@ token = TargetToken(jitcell_token) token.original_jitcell_token = jitcell_token all_target_tokens.append(token) - if label.getdescr() is not jump.getdescr(): + if label.getdescr() is None or label.getdescr() is not jump.getdescr(): label_index = index_of_first(rop.LABEL, self.operations, 1) if label_index > 0: second_label = self.operations[label_index] diff --git a/rpython/jit/metainterp/optimizeopt/guard.py b/rpython/jit/metainterp/optimizeopt/guard.py --- a/rpython/jit/metainterp/optimizeopt/guard.py +++ b/rpython/jit/metainterp/optimizeopt/guard.py @@ -213,6 +213,7 @@ if len(others) > 0: # (2) replaced = False for i,other in enumerate(others): + assert guard is not other if guard.implies(other, self): # strengthend others[i] = guard @@ -223,6 +224,7 @@ continue elif other.implies(guard, self): # implied + guard.rd_accum_list = None self.guards[guard.index] = None # mark as 'do not emit' replaced = True continue @@ -300,6 +302,7 @@ for other in guards[1:]: transitive_guard = one.transitive_imply(other, self, loop) if transitive_guard: + transitive_guard.rd_accum_list = None other.set_to_none(loop.operations) root_version.register_guard(transitive_guard, version) diff --git a/rpython/jit/metainterp/optimizeopt/test/test_vectorize.py b/rpython/jit/metainterp/optimizeopt/test/test_vectorize.py --- a/rpython/jit/metainterp/optimizeopt/test/test_vectorize.py +++ b/rpython/jit/metainterp/optimizeopt/test/test_vectorize.py @@ -1412,8 +1412,19 @@ guard_false(i33, descr=<ResumeGuardFalseDescr object at 0x7f89c54cddc0>) [p1, p0, p6, p7, i29, None, None] jump(p0, p1, p6, p7, i29, p14, p15) """ - #opt = self.schedule(self.parse_loop(trace)) - #self.debug_print_operations(opt.loop) + trace = """ + [p0, p1, p6, p7, p8, p11, p13, p15, i46, f43, i32, i36, i40] + i51 = int_lt(i46, i32) + guard_true(i51, descr=<Guard0x7fa98ec2b780>) [p1, p0, p15, p6, p7, p8, p11, p13, f43, i46] + i52 = int_lt(i46, i36) + guard_true(i52, descr=<Guard0x7fa98ec2b7d8>) [p1, p0, p11, i46, p6, p7, p8, p13, p15, f43, None] + f54 = getarrayitem_raw(i40, i46, descr=floatarraydescr) + f55 = float_add(f43, f54) + i56 = int_add(i46, 1) + jump(p0, p1, p6, p7, p8, p11, p13, p15, i56, f55, i32, i36, i40) + """ + opt = self.schedule(self.parse_loop(trace)) + self.debug_print_operations(opt.loop) class TestLLtype(BaseTestVectorize, LLtypeMixin): pass 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 @@ -509,15 +509,16 @@ # this needs to be done for renamed (accum arguments) version.renamed_inputargs = [ renamer.rename_map.get(arg,arg) for arg in version.inputargs ] self.appended_arg_count = len(sched_data.invariant_vector_vars) - for guard_node in self.dependency_graph.guards: - op = guard_node.getoperation() - failargs = op.getfailargs() - for i,arg in enumerate(failargs): - if arg is None: - continue - accum = arg.getaccum() - if accum: - accum.save_to_descr(op.getdescr(),i) + #for guard_node in self.dependency_graph.guards: + # op = guard_node.getoperation() + # failargs = op.getfailargs() + # for i,arg in enumerate(failargs): + # if arg is None: + # continue + # accum = arg.getaccum() + # if accum: + # pass + # #accum.save_to_descr(op.getdescr(),i) self.has_two_labels = len(sched_data.invariant_oplist) > 0 self.loop.operations = self.prepend_invariant_operations(sched_data) else: diff --git a/rpython/jit/metainterp/resume.py b/rpython/jit/metainterp/resume.py --- a/rpython/jit/metainterp/resume.py +++ b/rpython/jit/metainterp/resume.py @@ -35,13 +35,20 @@ self.pc = pc class AccumInfo(object): - __slots__ = ('prev', 'position', 'operation', 'box', 'loc') - def __init__(self, prev, position, operation, box): + __slots__ = ('prev', 'accum_operation', 'scalar_position', 'scalar_box', 'vector_loc') + def __init__(self, prev, position, operation, box, loc): self.prev = prev - self.operation = operation - self.position = position - self.box = box - self.loc = None + self.accum_operation = operation + self.scalar_position = position + self.scalar_box = box + self.vector_loc = loc + + def __repr__(self): + return 'AccumInfo(%s,%s,%s,%s,%s)' % (self.prev is None, + self.accum_operation, + self.scalar_position, + self.scalar_box, + self.vector_loc) def _ensure_parent_resumedata(framestack, n): target = framestack[n] 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 @@ -220,8 +220,9 @@ res = self.meta_interp(f, [60,58.4547]) assert res == f(60,58.4547) == 58.4547 - def test_accum(self): - myjitdriver = JitDriver(greens = [], reds = 'auto', vectorize=True) + @py.test.mark.parametrize('vec,vec_all',[(False,True),(True,False),(True,True),(False,False)]) + def test_accum(self, vec, vec_all): + myjitdriver = JitDriver(greens = [], reds = 'auto', vectorize=vec) T = lltype.Array(rffi.DOUBLE) def f(d, value): va = lltype.malloc(T, d, flavor='raw', zero=True) @@ -239,7 +240,7 @@ i += 1 lltype.free(va, flavor='raw') return r - res = self.meta_interp(f, [60,0.5], vec=True) + res = self.meta_interp(f, [60,0.5], vec=vec, vec_all=vec_all) assert res == f(60,0.5) == 60*0.5 _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit