[pypy-commit] pypy vecopt2: extended memory ref analysis to consider division as well, added some tests
plan_rich
noreply at buildbot.pypy.org
Tue May 5 09:45:26 CEST 2015
Author: Richard Plangger <rich at pasra.at>
Branch: vecopt2
Changeset: r77078:a1985466b222
Date: 2015-03-13 16:13 +0100
http://bitbucket.org/pypy/pypy/changeset/a1985466b222/
Log: extended memory ref analysis to consider division as well, added
some tests added a simple test to test the whole optimizer on a very
basic loop
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
@@ -18,13 +18,13 @@
Representation is an adjacent list. The number of edges between the
vertices is expected to be small.
"""
- def __init__(self, optimizer, loop):
- self.loop = loop
- self.operations = loop.operations
+ def __init__(self, optimizer):
+ self.loop = optimizer.loop
+ self.operations = self.loop.operations
self.optimizer = optimizer
self.adjacent_list = [ [] for i in range(len(self.operations)) ]
- self.build_dependencies(loop.operations)
+ self.build_dependencies(self.operations)
def build_dependencies(self, operations):
""" This is basically building the definition-use chain and saving this
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
@@ -14,28 +14,30 @@
return 'NotAVectorizeableLoop()'
def optimize_vector(metainterp_sd, jitdriver_sd, loop, optimizations):
- opt = OptVectorize(metainterp_sd, jitdriver_sd, loop, optimizations)
+ opt = VectorizingOptimizer(metainterp_sd, jitdriver_sd, loop, optimizations)
try:
opt.propagate_all_forward()
+ # TODO
+ def_opt = Optimizer(metainterp_sd, jitdriver_sd, loop, optimizations)
+ def_opt.propagate_all_forward()
except NotAVectorizeableLoop:
# vectorization is not possible, propagate only normal optimizations
def_opt = Optimizer(metainterp_sd, jitdriver_sd, loop, optimizations)
def_opt.propagate_all_forward()
-class VectorizeOptimizer(Optimizer):
- def setup(self):
- pass
-
-class OptVectorize(Optimization):
+class VectorizingOptimizer(Optimizer):
""" Try to unroll the loop and find instructions to group """
def __init__(self, metainterp_sd, jitdriver_sd, loop, optimizations):
- self.optimizer = VectorizeOptimizer(metainterp_sd, jitdriver_sd,
- loop, optimizations)
+ Optimizer.__init__(self, metainterp_sd, jitdriver_sd, loop, optimizations)
self.vec_info = LoopVectorizeInfo()
self.memory_refs = []
self.dependency_graph = None
+ def emit_unrolled_operation(self, op):
+ self._last_emitted_op = op
+ self._newoperations.append(op)
+
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.
@@ -58,15 +60,14 @@
iterations = [operations]
label_op_args = [self.getvalue(box).get_key_box() for box in label_op.getarglist()]
values = [self.getvalue(box) for box in label_op.getarglist()]
- #values[0].make_nonnull(self.optimizer)
jump_op_args = jump_op.getarglist()
rename_map = {}
+ self.emit_unrolled_operation(label_op)
for unroll_i in range(2, unroll_factor+1):
# for each unrolling factor the boxes are renamed.
self._rename_arguments_ssa(rename_map, label_op_args, jump_op_args)
- iteration_ops = []
for op in operations:
copied_op = op.clone()
@@ -86,7 +87,7 @@
pass
self.vec_info._op_index = op_index
- iteration_ops.append(copied_op)
+ self.emit_unrolled_operation(copied_op)
op_index += 1
self.vec_info.inspect_operation(copied_op)
@@ -104,14 +105,7 @@
# map will be rebuilt, the jump operation has been updated already
rename_map.clear()
- iterations.append(iteration_ops)
-
- # unwrap the loop nesting.
- loop.operations.append(label_op)
- for iteration in iterations:
- for op in iteration:
- loop.operations.append(op)
- loop.operations.append(jump_op)
+ self.emit_unrolled_operation(jump_op)
def _gather_trace_information(self, loop):
for i,op in enumerate(loop.operations):
@@ -132,10 +126,9 @@
def propagate_all_forward(self):
- loop = self.optimizer.loop
- self.optimizer.clear_newoperations()
+ self.clear_newoperations()
- self._gather_trace_information(loop)
+ self._gather_trace_information(self.loop)
byte_count = self.vec_info.smallest_type_bytes
if byte_count == 0:
@@ -144,22 +137,25 @@
unroll_factor = self.get_estimated_unroll_factor()
- self.unroll_loop_iterations(loop, unroll_factor)
+ self.unroll_loop_iterations(self.loop, unroll_factor)
- self.build_dependencies()
+ self.loop.operations = self.get_newoperations();
+ self.clear_newoperations();
+
+ self.build_dependency_graph()
+ self.find_adjacent_memory_refs()
def build_dependency_graph(self):
- self.dependency_graph = DependencyGraph(self.optimizer,
- self.optimizer.loop)
+ self.dependency_graph = DependencyGraph(self)
def find_adjacent_memory_refs(self):
""" the pre pass already builds a hash of memory references and the
operations. Since it is in SSA form there is no array index. Indices
are flattend. If there are two array accesses in the unrolled loop
i0,i1 and i1 = int_add(i0,c), then i0 = i0 + 0, i1 = i0 + 1 """
- loop = self.optimizer.loop
+ loop = self.loop
operations = loop.operations
- integral_mod = IntegralMod(self.optimizer)
+ integral_mod = IntegralMod(self)
for opidx,memref in self.vec_info.memory_refs.items():
integral_mod.reset()
while True:
diff --git a/rpython/jit/metainterp/test/test_vectorize.py b/rpython/jit/metainterp/test/test_vectorize.py
new file mode 100644
--- /dev/null
+++ b/rpython/jit/metainterp/test/test_vectorize.py
@@ -0,0 +1,51 @@
+import py
+
+from rpython.jit.metainterp.warmspot import ll_meta_interp, get_stats
+from rpython.jit.metainterp.test.support import LLJitMixin
+from rpython.jit.codewriter.policy import StopAtXPolicy
+from rpython.jit.metainterp.resoperation import rop
+from rpython.jit.metainterp import history
+from rpython.rlib.jit import JitDriver, hint, set_param
+from rpython.rlib.objectmodel import compute_hash
+from rpython.rtyper.lltypesystem import lltype, rffi
+from rpython.rlib.rarithmetic import r_uint
+from rpython.rlib.rawstorage import (alloc_raw_storage, raw_storage_setitem,
+ free_raw_storage, raw_storage_getitem)
+
+class VectorizeTest(object):
+ enable_opts = ''
+
+ automatic_promotion_result = {
+ 'int_add' : 6, 'int_gt' : 1, 'guard_false' : 1, 'jump' : 1,
+ 'guard_value' : 3
+ }
+
+ def meta_interp(self, f, args, policy=None):
+ return ll_meta_interp(f, args, enable_opts=self.enable_opts,
+ policy=policy,
+ CPUClass=self.CPUClass,
+ type_system=self.type_system)
+
+ def test_simple_raw_load(self):
+ myjitdriver = JitDriver(greens = [],
+ reds = ['i', 'res', 'va'],
+ vectorize=True)
+ def f():
+ res = r_uint(0)
+ va = alloc_raw_storage(32, zero=True)
+ for i in range(32):
+ raw_storage_setitem(va, i, rffi.cast(rffi.UCHAR,i))
+ i = 0
+ while i < 32:
+ myjitdriver.can_enter_jit(i=i, res=res, va=va)
+ myjitdriver.jit_merge_point(i=i, res=res, va=va)
+ res += raw_storage_getitem(rffi.UCHAR,va,i)
+ i += 1
+ free_raw_storage(va)
+ return res
+ res = self.meta_interp(f, [])
+ assert res == sum(range(32))
+ self.check_trace_count(1)
+
+class TestLLtype(VectorizeTest, LLJitMixin):
+ pass
More information about the pypy-commit
mailing list