Author: Richard Plangger <planri...@gmail.com> Branch: zarch-simd-support Changeset: r87072:1ea1c6504c10 Date: 2016-09-13 15:56 +0200 http://bitbucket.org/pypy/pypy/changeset/1ea1c6504c10/
Log: do not generate a new operation for index calc if it can be expressed as a single operation 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 @@ -993,6 +993,23 @@ self.next_nonconst = None self.current_end = None + def calculated_by(self, op): + # quick check to indicate if this operation is not directly expressable using + # the operation in the op parameter. + if op.getopnum() == rop.INT_ADD: + a0 = op.getarg(0) + a1 = op.getarg(1) + if a0 is self.var and a1.is_constant() and a1.getint() == self.constant: + return True + if a1 is self.var and a0.is_constant() and a0.getint() == self.constant: + return True + if op.getopnum() == rop.INT_SUB: + a0 = op.getarg(0) + a1 = op.getarg(1) + if a0 is self.var and a1.is_constant() and a1.getint() == self.constant: + return True + return False + def stride_const(self): return self.next_nonconst is None 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 @@ -49,7 +49,8 @@ if arg.is_constant() or arg.is_inputarg(): continue if arg not in self.seen: - needs_resolving[arg] = None + box = self.renamer.rename_box(arg) + needs_resolving[box] = None indexvars = self.graph.index_vars i = len(delayed)-1 @@ -60,18 +61,32 @@ # either it is a normal operation, or we know that there is a linear combination del needs_resolving[op] if op in indexvars: - indexvar = indexvars[op] - last = None - for operation in indexvar.get_operations(): - self.append_to_oplist(operation) - last = operation - if last: - indexvars[last] = indexvar - self.renamer.start_renaming(op, last) + opindexvar = indexvars[op] + # there might be a variable already, that + # calculated the index variable, thus just reuse it + for var, indexvar in indexvars.items(): + if indexvar == opindexvar and var in self.seen: + self.renamer.start_renaming(op, var) + break + else: + if opindexvar.calculated_by(op): + # just append this operation + self.seen[op] = None + self.append_to_oplist(op) + else: + # here is an easier way to calculate just this operation + last = op + for operation in opindexvar.get_operations(): + self.append_to_oplist(operation) + last = operation + indexvars[last] = opindexvar + self.renamer.start_renaming(op, last) + self.seen[op] = None + self.seen[last] = None else: self.resolve_delayed(needs_resolving, delayed, op) self.append_to_oplist(op) - self.seen[op] = None + self.seen[op] = None if len(delayed) > i: del delayed[i] i -= 1 @@ -84,14 +99,20 @@ self.renamer.rename(op) self.oplist.append(op) + def schedule(self): + self.prepare() + Scheduler().walk_and_emit(self) + self.post_schedule() + def post_schedule(self): loop = self.graph.loop + jump = loop.jump if self.delayed: # some operations can be delayed until the jump instruction, # handle them here - self.resolve_delayed({}, self.delayed, loop.jump) + self.resolve_delayed({}, self.delayed, jump) + self.renamer.rename(jump) loop.operations = self.oplist - self.renamer.rename(loop.jump) def profitable(self): return True @@ -120,8 +141,10 @@ delayed.append(node) node.delayed = None provides = node.provides() + op = node.getoperation() if len(provides) == 0: - self.delayed.append(node) + for n in delayed: + self.delayed.append(n) else: for to in node.provides(): tnode = to.target_node() @@ -187,13 +210,14 @@ def post_emit(self, node): pass - def pre_emit(self, node, pack_first=True): - delayed = node.delayed + def pre_emit(self, orignode, pack_first=True): + delayed = orignode.delayed if delayed: # there are some nodes that have been delayed just for this operation if pack_first: - op = node.getoperation() + op = orignode.getoperation() self.resolve_delayed({}, delayed, op) + for node in delayed: op = node.getoperation() if op in self.seen: @@ -208,7 +232,7 @@ for to in node.provides(): tnode = to.target_node() self.delegate_delay(tnode, [node]) - node.delayed = None + orignode.delayed = None class Scheduler(object): """ Create an instance of this class to (re)schedule a vector trace. """ diff --git a/rpython/jit/metainterp/optimizeopt/test/test_schedule.py b/rpython/jit/metainterp/optimizeopt/test/test_schedule.py --- a/rpython/jit/metainterp/optimizeopt/test/test_schedule.py +++ b/rpython/jit/metainterp/optimizeopt/test/test_schedule.py @@ -5,7 +5,7 @@ from rpython.jit.metainterp.optimizeopt.renamer import Renamer from rpython.jit.metainterp.optimizeopt.vector import (VecScheduleState, Pack, Pair, NotAProfitableLoop, VectorizingOptimizer, GenericCostModel, - PackSet) + PackSet, SchedulerState) from rpython.jit.backend.llsupport.vector_ext import VectorExt from rpython.jit.metainterp.optimizeopt.dependency import Node, DependencyGraph from rpython.jit.metainterp.optimizeopt.schedule import Scheduler @@ -460,5 +460,18 @@ state.expand(['d','d','c'], 'ddc') assert state.find_expanded(['d','d','c']) == 'ddc' - - + def test_delayed_schedule(self): + loop = self.parse(""" + [i0] + i1 = int_add(i0,1) + i2 = int_add(i0,1) + jump(i2) + """) + loop.prefix_label = None + loop.label = ResOperation(rop.LABEL, loop.inputargs) + ops = loop.operations + loop.operations = ops[:-1] + loop.jump = ops[-1] + state = SchedulerState(self.cpu, DependencyGraph(loop)) + state.schedule() + assert len(loop.operations) == 1 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 @@ -262,11 +262,8 @@ # re-schedule the trace -> removes many pure operations graph = DependencyGraph(loop) - costmodel = GenericCostModel(self.cpu, self.cost_threshold) state = SchedulerState(self.cpu, graph) - state.prepare() - Scheduler().walk_and_emit(state) - state.post_schedule() + state.schedule() return loop.finaloplist(jitcell_token=jitcell_token, reset_label_token=False) _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit