Author: Richard Plangger <r...@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 _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit