[pypy-commit] pypy vecopt-merge: saving of accum state more explicit
plan_rich
noreply at buildbot.pypy.org
Sun Aug 23 15:14:45 CEST 2015
Author: Richard Plangger <rich at 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
More information about the pypy-commit
mailing list