Author: Richard Plangger <[email protected]>
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
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit