Author: Richard Plangger <[email protected]>
Branch: vecopt2
Changeset: r77087:911191f43398
Date: 2015-03-24 16:10 +0100
http://bitbucket.org/pypy/pypy/changeset/911191f43398/
Log: extended the test cases and removed a undiscovered bug in the
unrolling/renaming phase
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
@@ -1,4 +1,5 @@
import py
+import pytest
from rpython.rlib.objectmodel import instantiate
from rpython.jit.metainterp.optimizeopt.test.test_util import (
@@ -553,6 +554,34 @@
assert len(vopt.vec_info.memory_refs) == 2
assert len(vopt.pack_set.packs) == 1
+ def test_packset_init_2(self):
+ ops = """
+ [p0,i0]
+ i1 = int_add(i0, 1)
+ i2 = int_le(i1, 16)
+ guard_true(i2) [p0, i0]
+ i3 = getarrayitem_gc(p0, i1, descr=chararraydescr)
+ jump(p0,i1)
+ """
+ loop = self.parse_loop(ops)
+ vopt = self.init_pack_set(loop,15)
+ self.debug_print_operations(loop)
+ assert len(vopt.vec_info.memory_refs) == 16
+ assert len(vopt.pack_set.packs) == 15
+ for i in range(15):
+ x = (i+1)*4
+ y = x + 4
+ assert vopt.dependency_graph.independant(x,y)
+ mref1 = vopt.vec_info.memory_refs[x]
+ mref2 = vopt.vec_info.memory_refs[y]
+ assert mref1.is_adjacent_to(mref2)
+ for pack in vopt.pack_set.packs:
+ if pack.left.op_idx == (i+1)*4 and \
+ pack.right.op_idx == (i+1)*4 + 4:
+ break
+ else:
+ pytest.fail("must find a pack set for {x},{y}".format(x=x,y=y))
+
def test_isomorphic_operations(self):
ops_src = """
[p1,p0,i0]
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
@@ -48,20 +48,9 @@
self._newoperations.append(op)
return True
- def _rename_arguments_ssa(self, rename_map, label_args, jump_args):
- # fill the map with the renaming boxes. keys are boxes from the label
- # values are the target boxes.
-
- # it is assumed that #label_args == #jump_args
- for i in range(len(label_args)):
- la = label_args[i]
- ja = jump_args[i]
- if la != ja:
- rename_map[la] = ja
-
- def unroll_loop_iterations(self, loop, unroll_factor):
- """ Unroll the loop X times. Unroll_factor of 0 = no unrolling,
- 1 once, ...
+ def unroll_loop_iterations(self, loop, unroll_count):
+ """ Unroll the loop X times. unroll_count is an integral how
+ often to further unroll the loop.
"""
op_count = len(loop.operations)
@@ -82,22 +71,23 @@
operations.append(op)
self.emit_unrolled_operation(op)
self.vec_info.inspect_operation(op)
- jump_op_args = jump_op.getarglist()
+ orig_jump_args = jump_op.getarglist()[:]
+ # it is assumed that #label_args == #jump_args
+ label_arg_count = len(orig_jump_args)
rename_map = {}
- for i in range(0, unroll_factor):
- # for each unrolling factor the boxes are renamed.
- self._rename_arguments_ssa(rename_map, label_op_args, jump_op_args)
+ for i in range(0, unroll_count):
+ # fill the map with the renaming boxes. keys are boxes from the
label
+ for i in range(label_arg_count):
+ la = label_op.getarg(i)
+ ja = jump_op.getarg(i)
+ if ja in rename_map:
+ ja = rename_map[ja]
+ if la != ja:
+ rename_map[la] = ja
+ #
for op in operations:
copied_op = op.clone()
-
- if copied_op.result is not None:
- # every result assigns a new box, thus creates an entry
- # to the rename map.
- new_assigned_box = copied_op.result.clonebox()
- rename_map[copied_op.result] = new_assigned_box
- copied_op.result = new_assigned_box
-
args = copied_op.getarglist()
for i, arg in enumerate(args):
try:
@@ -105,7 +95,6 @@
copied_op.setarg(i, value)
except KeyError:
pass
-
# not only the arguments, but also the fail args need
# to be adjusted. rd_snapshot stores the live variables
# that are needed to resume.
@@ -113,23 +102,27 @@
new_snapshot = self.clone_snapshot(copied_op.rd_snapshot,
rename_map)
copied_op.rd_snapshot = new_snapshot
-
+ #
+ if copied_op.result is not None:
+ # every result assigns a new box, thus creates an entry
+ # to the rename map.
+ new_assigned_box = copied_op.result.clonebox()
+ rename_map[copied_op.result] = new_assigned_box
+ copied_op.result = new_assigned_box
+ #
self.emit_unrolled_operation(copied_op)
self.vec_info.inspect_operation(copied_op)
- # the jump arguments have been changed
- # if label(iX) ... jump(i(X+1)) is called, at the next unrolled
loop
- # must look like this: label(i(X+1)) ... jump(i(X+2))
-
- args = jump_op.getarglist()
- for i, arg in enumerate(args):
- try:
- value = rename_map[arg]
- jump_op.setarg(i, value)
- except KeyError:
- pass
- # map will be rebuilt, the jump operation has been updated already
- rename_map.clear()
+ # the jump arguments have been changed
+ # if label(iX) ... jump(i(X+1)) is called, at the next unrolled loop
+ # must look like this: label(i(X+1)) ... jump(i(X+2))
+ args = jump_op.getarglist()
+ for i, arg in enumerate(args):
+ try:
+ value = rename_map[arg]
+ jump_op.setarg(i, value)
+ except KeyError:
+ pass
if self.last_debug_merge_point is not None:
self._last_emitted_op = self.last_debug_merge_point
@@ -165,8 +158,8 @@
if byte_count == 0:
return 0
simd_vec_reg_bytes = 16 # TODO get from cpu
- unroll_factor = simd_vec_reg_bytes // byte_count
- return unroll_factor-1 # it is already unrolled once
+ unroll_count = simd_vec_reg_bytes // byte_count
+ return unroll_count-1 # it is already unrolled once
def propagate_all_forward(self):
@@ -179,9 +172,9 @@
# stop, there is no chance to vectorize this trace
raise NotAVectorizeableLoop()
- unroll_factor = self.get_unroll_count()
+ unroll_count = self.get_unroll_count()
- self.unroll_loop_iterations(self.loop, unroll_factor)
+ self.unroll_loop_iterations(self.loop, unroll_count)
self.loop.operations = self.get_newoperations();
self.clear_newoperations();
@@ -205,31 +198,20 @@
for opidx,memref in self.vec_info.memory_refs.items():
integral_mod.reset()
while True:
+ for dep in self.dependency_graph.instr_dependencies(opidx):
+ if dep.idx_from < opidx:
+ op = operations[dep.idx_from]
+ if op.result == memref.origin:
+ opidx = dep.idx_from
+ break
+ else:
+ break # cannot go further, this might be the label, or a
constant
- for dep in self.dependency_graph.instr_dependencies(opidx):
- # this is a use, thus if dep is not a defintion
- # it points back to the definition
- # if memref.origin == dep.defined_arg and not
dep.is_definition:
- if memref.origin in dep.args:
- # if is_definition is false the params is swapped
- # idx_to attributes points to define
- def_op = operations[dep.idx_from]
- opidx = dep.idx_from
- break
- else:
- # this is an error in the dependency graph
- raise RuntimeError("a variable usage does not have a " +
- " definition. Cannot continue!")
-
- op = operations[opidx]
- if op.getopnum() == rop.LABEL:
- break
-
- integral_mod.inspect_operation(def_op)
+ integral_mod.inspect_operation(op)
if integral_mod.is_const_mod:
integral_mod.update_memory_ref(memref)
else:
- break
+ break # an operation that is not tractable
self.pack_set = PackSet(self.dependency_graph, operations)
memory_refs = self.vec_info.memory_refs.items()
@@ -265,8 +247,7 @@
""" Described in the paper ``Instruction-Isomorphism in Program
Execution''.
I think this definition is to strict. TODO -> find another reference
For now it must have the same instruction type, the array parameter must
be equal,
- and it must be of the same type (both size in bytes and type of array)
- .
+ and it must be of the same type (both size in bytes and type of array).
"""
if l_op.getopnum() == r_op.getopnum() and \
l_op.getarg(0) == r_op.getarg(0):
@@ -425,7 +406,7 @@
a1 = self.optimizer.getvalue(box_a1)
self.is_const_mod = True
if a0.is_constant() and a1.is_constant():
- # here these factor becomes a constant, thus it is
+ # here this factor becomes a constant, thus it is
# handled like any other additive operation
self.used_box = None
self.constant += self._update_additive(box_a0.getint() {cop} \
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit