Author: Richard Plangger <r...@pasra.at> Branch: vecopt-merge Changeset: r79204:9e571b42712d Date: 2015-08-24 15:27 +0200 http://bitbucket.org/pypy/pypy/changeset/9e571b42712d/
Log: memory error does not happen anymore on vecopt-merge 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 @@ -591,14 +591,14 @@ rawstart, fullsize) return AsmInfo(ops_offset, startpos + rawstart, codeendpos - startpos, rawstart) - def stitch_bridge(self, faildescr, version): + def stitch_bridge(self, faildescr, target): """ Stitching means that one can enter a bridge with a complete different register allocation. This needs remapping which is done here for both normal registers and accumulation registers. Why? Because this only generates a very small junk of memory, instead of duplicating the loop assembler for each faildescr! """ - asminfo, bridge_faildescr, compiled_version, looptoken = version._compiled + asminfo, bridge_faildescr, version, looptoken = target assert isinstance(bridge_faildescr, ResumeGuardDescr) assert isinstance(faildescr, ResumeGuardDescr) assert asminfo.rawstart != 0 @@ -612,7 +612,7 @@ self.mc.force_frame_size(DEFAULT_FRAME_BYTES) # if accumulation is saved at the guard, we need to update it here! guard_locs = self.rebuild_faillocs_from_descr(faildescr, version.inputargs) - bridge_locs = self.rebuild_faillocs_from_descr(bridge_faildescr, compiled_version.inputargs) + bridge_locs = self.rebuild_faillocs_from_descr(bridge_faildescr, version.inputargs) guard_accum_info = faildescr.rd_accum_list # O(n^2), but usually you only have at most 1 fail argument while guard_accum_info: 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 @@ -162,7 +162,7 @@ if loop.versions is not None: # every different loop version must update their target tokens - for version in loop.versions[1:]: + for version in loop.versions: version.update_token(jitcell_token, all_target_tokens) if not loop.quasi_immutable_deps: @@ -194,12 +194,12 @@ if loop.versions: # compile each version once for the first fail descr! # this assumes that the root trace (= loop) is already compiled - root = loop.versions[0] - for faildescr in root.faildescrs: - assert isinstance(faildescr, CompileLoopVersionDescr) - version = faildescr.version - if not version or version.compiled(): + to_stitch = [] + for version in loop.versions: + if not version.faildescrs: continue + faildescr = version.faildescrs[0] + assert isinstance(faildescr, ResumeGuardDescr) vl = create_empty_loop(metainterp) vl.inputargs = version.inputargs vl.operations = version.operations @@ -209,20 +209,14 @@ version.operations, jitcell_token) record_loop_or_bridge(metainterp_sd, vl) assert asminfo is not None - version._compiled = (asminfo, faildescr, faildescr.version, jitcell_token) - faildescr.version = None + + for i,fd in enumerate(version.faildescrs): + if i == 0: + continue + to_stitch.append((fd, (asminfo, faildescr, version, jitcell_token))) # stitch to the trace loop - for lv in loop.versions: - if not lv.compiled(): - # the version was never compiled, do not bother - # to assign it's fail descr - continue - for faildescr in lv.faildescrs: - assert isinstance(faildescr, CompileLoopVersionDescr) - version = faildescr.version - if version and version.compiled(): - cpu.stitch_bridge(faildescr, version) - faildescr.version = None + for fd, param in to_stitch: + cpu.stitch_bridge(fd, param) loop.versions = None def compile_retrace(metainterp, greenkey, start, @@ -531,7 +525,7 @@ class ResumeGuardDescr(ResumeDescr): _attrs_ = ('rd_numb', 'rd_count', 'rd_consts', 'rd_virtuals', 'rd_frame_info_list', 'rd_pendingfields', 'rd_accum_list', - 'status') + 'status', 'version') rd_numb = lltype.nullptr(NUMBERING) rd_count = 0 @@ -542,6 +536,7 @@ rd_accum_list = None status = r_uint(0) + version = None def copy_all_attributes_from(self, other): assert isinstance(other, ResumeGuardDescr) @@ -746,11 +741,6 @@ class CompileLoopVersionDescr(ResumeGuardDescr): guard_opnum = rop.GUARD_EARLY_EXIT - operations = None - inputargs = None - faillocs = None - version = None - def handle_fail(self, deadframe, metainterp_sd, jitdriver_sd): assert 0, "this guard must never fail" 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 @@ -744,60 +744,31 @@ create one instance and attach it to a guard descr. If not attached to a descriptor, it will not be compiled. """ - def __init__(self, loop): - self.faildescrs = [] - self._compiled = (None,None,None,None) - if loop: - self.operations = self.copy_operations(loop.operations) + _compiled = (None,None,None,None) + inputargs = None + renamed_inputargs = None + + def __init__(self, operations): + self.faildescrs = None + self.stitchdescr = {} + self.operations = operations + + def setup_once(self): + if self.operations: idx = index_of_first(rop.LABEL, self.operations) assert idx >= 0 label = self.operations[idx] self.inputargs = label.getarglist() self.renamed_inputargs = label.getarglist() - else: - self.operations = None - self.inputargs = None - self.renamed_inputargs = None + # register the faildescr for later stitching + for op in self.operations: + if op.is_guard(): + descr = op.getdescr() + if descr.loop_version(): + self.faildescrs.append(descr) - def compiled(self): - if self.operations is None: - # root version must always be compiled - return True - - return self._compiled[0] is not None - - def copy_operations(self, operations): - from rpython.jit.metainterp.compile import (ResumeGuardDescr, - CompileLoopVersionDescr) - ignore = (rop.DEBUG_MERGE_POINT,) - oplist = [] - for op in operations: - if op.getopnum() in ignore: - continue - cloned = op.clone() - oplist.append(cloned) - if cloned.is_guard(): - olddescr = cloned.getdescr() - if not olddescr: - continue - descr = olddescr.clone() - cloned.setdescr(descr) - if olddescr.loop_version(): - # copy the version - assert isinstance(olddescr, CompileLoopVersionDescr) - assert isinstance(descr, CompileLoopVersionDescr) - descr.version = olddescr.version - self.faildescrs.append(descr) - return oplist - - def register_guard(self, op, version): - from rpython.jit.metainterp.compile import CompileLoopVersionDescr - assert isinstance(op, GuardResOp) - descr = op.getdescr() - if not descr.loop_version(): - assert 0, "cannot register a guard that is not a CompileLoopVersionDescr" - assert isinstance(descr, CompileLoopVersionDescr) - descr.version = version + def register_guard(self, op, descr, version): + assert descr.loop_version() self.faildescrs.append(descr) # note: stitching a guard must resemble the order of the label # otherwise a wrong mapping is handed to the register allocator @@ -903,12 +874,9 @@ return self.operations[index] return None - def snapshot(self): - if len(self.versions) == 0: - # create a root version, simplyfies the code in compile.py - self.versions.append(LoopVersion(None)) - root_version = self.versions[0] - version = LoopVersion(self) + def snapshot(self, operations): + version = LoopVersion(operations) + version.setup_once() self.versions.append(version) return version 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 @@ -151,10 +151,10 @@ def set_to_none(self, operations): assert operations[self.index] is self.op operations[self.index] = None - descr = self.op.getdescr() - if descr and descr.loop_version(): - assert isinstance(descr, CompileLoopVersionDescr) - descr.version = None + #descr = self.op.getdescr() + #if descr and descr.loop_version(): + # assert isinstance(descr, CompileLoopVersionDescr) + # descr.version = None if operations[self.index-1] is self.cmp_op: operations[self.index-1] = None @@ -276,10 +276,11 @@ continue descr = op.getdescr() if descr.loop_version(): - root_version.register_guard(op, version) + assert isinstance(descr, ResumeGuardDescr) + root_version.register_guard(op, descr, version) if user_code: - version = loop.snapshot() + version = loop.snapshot(copy_operations(loop.operations)) self.eliminate_array_bound_checks(loop, root_version, version) def emit_operation(self, op): @@ -302,7 +303,9 @@ transitive_guard = one.transitive_imply(other, self, loop) if transitive_guard: other.set_to_none(loop.operations) - root_version.register_guard(transitive_guard, version) + descr = transitive_guard.getdescr() + assert isinstance(descr, ResumeGuardDescr) + root_version.register_guard(transitive_guard, descr, version) if self.has_two_labels: oplist = [loop.operations[0]] + self._newoperations + \ @@ -312,3 +315,23 @@ loop.operations = self._newoperations + \ [op for op in loop.operations if op] +def copy_operations(operations): + ignore = (rop.DEBUG_MERGE_POINT,) + oplist = [] + for op in operations: + if op.getopnum() in ignore: + continue + cloned = op.clone() + oplist.append(cloned) + if cloned.is_guard(): + olddescr = cloned.getdescr() + if not olddescr: + continue + assert isinstance(olddescr, ResumeGuardDescr) + descr = olddescr.clone() + assert isinstance(descr, ResumeGuardDescr) + cloned.setdescr(descr) + if olddescr.loop_version(): + # copy the version + descr.version = olddescr.version + return oplist 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 @@ -23,7 +23,7 @@ from rpython.jit.metainterp.optimizeopt.schedule import (VecScheduleData, Scheduler, Pack, Pair, AccumPair, vectorbox_outof_box, getpackopnum, getunpackopnum, PackType, determine_input_output_types) -from rpython.jit.metainterp.optimizeopt.guard import GuardStrengthenOpt +from rpython.jit.metainterp.optimizeopt.guard import GuardStrengthenOpt, copy_operations from rpython.jit.metainterp.resoperation import (rop, ResOperation, GuardResOp) from rpython.rlib import listsort from rpython.rlib.objectmodel import we_are_translated @@ -42,7 +42,7 @@ if user_code and user_loop_bail_fast_path(loop, warmstate): return # the original loop (output of optimize_unroll) - version = loop.snapshot() + version = loop.snapshot(copy_operations(loop.operations)) try: debug_start("vec-opt-loop") metainterp_sd.logger_noopt.log_loop(loop.inputargs, loop.operations, -2, None, None, "pre vectorize") _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit