Author: Richard Plangger <planri...@gmail.com> Branch: vecopt-merge Changeset: r80076:cbbff5a45632 Date: 2015-10-09 12:26 +0200 http://bitbucket.org/pypy/pypy/changeset/cbbff5a45632/
Log: small refactoring towards unpacking vector elements after the guard has failed diff --git a/rpython/jit/backend/llgraph/runner.py b/rpython/jit/backend/llgraph/runner.py --- a/rpython/jit/backend/llgraph/runner.py +++ b/rpython/jit/backend/llgraph/runner.py @@ -1061,20 +1061,20 @@ # ----------------------------------------------------- def _accumulate(self, descr, failargs, values): - accuminfo = descr.rd_accum_list - while accuminfo: - i = accuminfo.getpos_in_failargs() + info = descr.rd_vector_info + while info: + i = info.getpos_in_failargs() value = values[i] assert isinstance(value, list) - if accuminfo.accum_operation == '+': + if info.accum_operation == '+': value = sum(value) - elif accuminfo.accum_operation == '*': + elif info.accum_operation == '*': def prod(acc, x): return acc * x value = reduce(prod, value, 1) else: raise NotImplementedError("accum operator in fail guard") values[i] = value - accuminfo = accuminfo.next() + info = info.next() def fail_guard(self, descr, saved_data=None, extra_value=None): values = [] 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 @@ -558,7 +558,7 @@ self.current_clt.frame_info) self._check_frame_depth(self.mc, regalloc.get_gcmap()) bridgestartpos = self.mc.get_relative_pos() - self._accum_update_at_exit(arglocs, inputargs, faildescr, regalloc) + self._update_at_exit(arglocs, inputargs, faildescr, regalloc) frame_depth_no_fixed_size = self._assemble(regalloc, inputargs, operations) codeendpos = self.mc.get_relative_pos() self.write_pending_failure_recoveries(regalloc) @@ -610,15 +610,15 @@ guard_locs = self.rebuild_faillocs_from_descr(faildescr, version.inputargs) bridge_locs = self.rebuild_faillocs_from_descr(bridge_faildescr, version.inputargs) #import pdb; pdb.set_trace() - guard_accum_info = faildescr.rd_accum_list + guard_accum_info = faildescr.rd_vector_info # O(n^2), but usually you only have at most 1 fail argument while guard_accum_info: - bridge_accum_info = bridge_faildescr.rd_accum_list + bridge_accum_info = bridge_faildescr.rd_vector_info while bridge_accum_info: - if bridge_accum_info.scalar_position == guard_accum_info.scalar_position: + if bridge_accum_info.failargs_pos == guard_accum_info.failargs_pos: # the mapping might be wrong! - if bridge_accum_info.vector_loc is not guard_accum_info.vector_loc: - self.mov(guard_accum_info.vector_loc, bridge_accum_info.vector_loc) + if bridge_accum_info.location is not guard_accum_info.location: + self.mov(guard_accum_info.location, bridge_accum_info.location) bridge_accum_info = bridge_accum_info.next() guard_accum_info = guard_accum_info.next() @@ -1876,8 +1876,8 @@ self.mc.force_frame_size(DEFAULT_FRAME_BYTES) startpos = self.mc.get_relative_pos() # - self._accum_update_at_exit(guardtok.fail_locs, guardtok.failargs, - guardtok.faildescr, regalloc) + self._update_at_exit(guardtok.fail_locs, guardtok.failargs, + guardtok.faildescr, regalloc) # fail_descr, target = self.store_info_on_descr(startpos, guardtok) self.mc.PUSH(imm(fail_descr)) 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 @@ -322,10 +322,10 @@ if not descr: return faillocs assert isinstance(descr, AbstractFailDescr) - if descr.rd_accum_list: - accuminfo = descr.rd_accum_list + if descr.rd_vector_info: + accuminfo = descr.rd_vector_info while accuminfo: - accuminfo.vector_loc = faillocs[accuminfo.getpos_in_failargs()] + accuminfo.location = faillocs[accuminfo.getpos_in_failargs()] loc = self.loc(accuminfo.getoriginal()) faillocs[accuminfo.getpos_in_failargs()] = loc accuminfo = accuminfo.next() 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 @@ -74,20 +74,20 @@ index += 1 self.mc.PBLENDW_xxi(loc.value, temp.value, select) - def _accum_update_at_exit(self, fail_locs, fail_args, faildescr, regalloc): + def _update_at_exit(self, fail_locs, fail_args, faildescr, regalloc): """ If accumulation is done in this loop, at the guard exit some vector registers must be adjusted to yield the correct value """ if not isinstance(faildescr, ResumeGuardDescr): return assert regalloc is not None - accum_info = faildescr.rd_accum_list + accum_info = faildescr.rd_vector_info while accum_info: - pos = accum_info.scalar_position + pos = accum_info.getpos_in_failargs() scalar_loc = fail_locs[pos] - vector_loc = accum_info.vector_loc + vector_loc = accum_info.location # the upper elements will be lost if saved to the stack! - scalar_arg = accum_info.scalar_box + scalar_arg = accum_info.getoriginal() assert isinstance(vector_loc, RegLoc) if not isinstance(scalar_loc, RegLoc): scalar_loc = regalloc.force_allocate_reg(scalar_arg) 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 @@ -687,17 +687,9 @@ def clone(self): return self - def exits_early(self): - return False - - def attach_accum_info(self, pos, operator, arg, loc): - self.rd_accum_list = \ - AccumInfo(self.rd_accum_list, pos, operator, arg, loc) - def copy_all_attributes_from(self, other): pass - class AbstractResumeGuardDescr(ResumeDescr): _attrs_ = ('status',) @@ -873,10 +865,10 @@ self.rd_virtuals = other.rd_virtuals self.rd_numb = other.rd_numb # we don't copy status - if other.rd_accum_list: - self.rd_accum_list = other.rd_accum_list.clone() + if other.rd_vector_info: + self.rd_vector_info = other.rd_vector_info.clone() else: - other.rd_accum_list = None + other.rd_vector_info = None def store_final_boxes(self, guard_op, boxes, metainterp_sd): guard_op.setfailargs(boxes) @@ -907,6 +899,11 @@ def loop_version(self): return True + def clone(self): + cloned = CompileLoopVersionDescr() + cloned.copy_all_attributes_from(self) + return cloned + class AllVirtuals: llopaque = True cache = None 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 @@ -146,9 +146,9 @@ index = -1 final_descr = False - _attrs_ = ('adr_jump_offset', 'rd_locs', 'rd_loop_token', 'rd_accum_list') + _attrs_ = ('adr_jump_offset', 'rd_locs', 'rd_loop_token', 'rd_vector_info') - rd_accum_list = None + rd_vector_info = None def handle_fail(self, deadframe, metainterp_sd, jitdriver_sd): raise NotImplementedError @@ -164,6 +164,12 @@ # compile a loop version out of this guard? return False + def attach_vector_info(self, info): + from rpython.jit.metainterp.resume import VectorInfo + assert isinstance(info, VectorInfo) + info.prev = self.rd_vector_info + self.rd_vector_info = info + class BasicFinalDescr(AbstractFailDescr): final_descr = True 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 @@ -192,7 +192,7 @@ def exits_early(self): if self.op.is_guard(): descr = self.op.getdescr() - return isinstance(descr, compile.CompileLoopVersionDescr) + return descr.exits_early() return False def loads_from_complex_object(self): @@ -713,7 +713,7 @@ self.guard_argument_protection(guard_node, tracker) # descr = guard_op.getdescr() - if isinstance(descr, compile.CompileLoopVersionDescr): + if descr.exits_early(): return # handle fail args if guard_op.getfailargs(): 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 @@ -87,7 +87,7 @@ # guard descr = CompileLoopVersionDescr() descr.copy_all_attributes_from(self.op.getdescr()) - descr.rd_accum_list = None # do not copy the accum list + descr.rd_vector_info = None # do not copy the accum list assert isinstance(descr, ResumeGuardDescr) guard = ResOperation(self.op.getopnum(), [compare], descr=descr) guard.setfailargs(loop.label.getarglist_copy()) diff --git a/rpython/jit/metainterp/optimizeopt/schedule.py b/rpython/jit/metainterp/optimizeopt/schedule.py --- a/rpython/jit/metainterp/optimizeopt/schedule.py +++ b/rpython/jit/metainterp/optimizeopt/schedule.py @@ -694,7 +694,8 @@ from rpython.jit.metainterp.compile import AbstractResumeGuardDescr assert isinstance(accum, AccumPack) assert isinstance(descr, AbstractResumeGuardDescr) - descr.attach_accum_info(i, accum.operator, arg, None) + info = AccumInfo(i, arg, accum.operator) + descr.attach_vector_info(info) seed = accum.getleftmostseed() failargs[i] = self.renamer.rename_map.get(seed, seed) diff --git a/rpython/jit/metainterp/optimizeopt/vector.py b/rpython/jit/metainterp/optimizeopt/vector.py --- a/rpython/jit/metainterp/optimizeopt/vector.py +++ b/rpython/jit/metainterp/optimizeopt/vector.py @@ -10,7 +10,6 @@ from rpython.jit.metainterp.resume import Snapshot from rpython.jit.metainterp.jitexc import NotAVectorizeableLoop, NotAProfitableLoop -#from rpython.jit.metainterp.optimizeopt.unroll import optimize_unroll from rpython.jit.metainterp.compile import (CompileLoopVersionDescr, ResumeDescr) from rpython.jit.metainterp.history import (INT, FLOAT, VECTOR, ConstInt, ConstFloat, TargetToken, JitCellToken, AbstractFailDescr) 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 @@ -34,38 +34,67 @@ self.jitcode = jitcode self.pc = pc -class AccumInfo(object): - _attrs_ = ('prev', 'accum_operation', 'scalar_position', 'scalar_box', 'vector_loc') +class VectorInfo(object): + """ + prev: the previous VectorInfo or None + failargs_pos: the index where to find it in the fail arguments + location: the register location (an integer), specified by the backend + variable: the original variable that lived at failargs_pos + """ + _attrs_ = ('prev', 'failargs_pos', 'location', 'variable') + prev = None + failargs_pos = -1 + location = None + variable = None - def __init__(self, prev, position, operation, box, loc): - self.prev = prev - self.accum_operation = operation - self.scalar_position = position - self.scalar_box = box - self.vector_loc = loc - - def getoriginal(self): - return self.scalar_box + def __init__(self, position, variable): + self.failargs_pos = position + self.variable = variable def getpos_in_failargs(self): - return self.scalar_position + return self.failargs_pos def next(self): return self.prev + def getoriginal(self): + return self.variable + def clone(self): prev = None if self.prev: prev = self.prev.clone() - return AccumInfo(prev, self.scalar_position, self.accum_operation, - self.scalar_box, None) + return self.instance_clone(prev) + + def instance_clone(self, prev): + raise NotImplementedError + +class UnpackAtExitInfo(VectorInfo): + def instance_clone(self, prev): + info = UnpackAtExitInfo(self.failargs_pos, self.variable) + info.prev = prev + return info + +class AccumInfo(VectorInfo): + _attrs_ = ('accum_operation', 'scalar') + + def __init__(self, position, variable, operation): + VectorInfo.__init__(self, position, variable) + self.accum_operation = operation + + def instance_clone(self, prev): + info = AccumInfo(self.failargs_pos, self.variable, + self.accum_operation) + info.location = self.location + info.prev = prev + return info 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) + self.failargs_pos, + self.variable, + self.location) def _ensure_parent_resumedata(framestack, n): target = framestack[n] _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit