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