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