Author: Richard Plangger <[email protected]>
Branch: vecopt-merge
Changeset: r79052:8fa916fbce20
Date: 2015-08-19 13:19 +0200
http://bitbucket.org/pypy/pypy/changeset/8fa916fbce20/
Log: further cut down the search space to move guards to an earlier
position, at the same time it seems that I have made it weaker. some
guards are not moved anymore (need investigation)
diff --git a/rpython/jit/metainterp/compile.py
b/rpython/jit/metainterp/compile.py
--- a/rpython/jit/metainterp/compile.py
+++ b/rpython/jit/metainterp/compile.py
@@ -674,6 +674,9 @@
cloned.copy_all_attributes_from(self)
return cloned
+ def exits_early(self):
+ return True
+
class ResumeGuardNonnullDescr(ResumeGuardDescr):
guard_opnum = rop.GUARD_NONNULL
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
@@ -4,6 +4,7 @@
from rpython.jit.metainterp.optimizeopt.util import make_dispatcher_method
from rpython.jit.metainterp.resoperation import (rop, GuardResOp, ResOperation)
from rpython.jit.metainterp.resume import Snapshot
+from rpython.jit.metainterp.compile import ResumeGuardDescr
from rpython.jit.codewriter.effectinfo import EffectInfo
from rpython.jit.metainterp.history import (BoxPtr, ConstPtr, ConstInt, BoxInt,
Box, Const, BoxFloat, AbstractValue)
@@ -61,8 +62,13 @@
count -= 1
while i < count:
op = self.path[i].getoperation()
- if op.getopnum() != rop.GUARD_EARLY_EXIT and not
op.is_always_pure():
+ if not op.is_always_pure():
return False
+ if op.is_guard():
+ descr = op.getdescr()
+ assert isinstance(descr, ResumeGuardDescr)
+ if not descr or not descr.exits_early():
+ return False
i += 1
return True
@@ -286,9 +292,8 @@
else:
iterdir = node.provides()
if index >= len(iterdir):
- #if blacklist:
- #blacklist_visit[node] = None
- # print "blacklisting 1", node, "path",
'->'.join([str(p.opidx) for p in path.path])
+ if blacklist:
+ blacklist_visit[node] = None
continue
else:
next_dep = iterdir[index]
@@ -297,7 +302,6 @@
if index < len(iterdir):
worklist.append((index, node, pathlen))
else:
- print "blacklisting 2", node, "path",
'->'.join([str(p.opidx) for p in path.path])
blacklist_visit[node] = None
path.cut_off_at(pathlen)
path.walk(next_node)
@@ -385,9 +389,6 @@
return self.to == to
def points_at(self, at):
return self.at == at
- def i_points_at(self, idx):
- # REM
- return self.at.opidx == idx
def add_dependency(self, at, to, arg):
self.args.append((at,arg))
@@ -576,17 +577,16 @@
# pass 2 correct guard dependencies
for guard_node in self.guards:
self.build_guard_dependencies(guard_node, tracker)
- # pass 3 find schedulable nodes
- jump_node = self.nodes[jump_pos]
- label_node = self.nodes[label_pos]
+
+ def prepare_for_scheduling(self):
+ jump_node = self.nodes[len(self.nodes)-1]
+ jump_node.emitted = True
+ label_node = self.nodes[0]
for node in self.nodes:
- if node != jump_node:
- if node.depends_count() == 0:
- self.schedulable_nodes.insert(0, node)
- # every leaf instruction points to the jump_op. in theory
every instruction
- # points to jump_op. this forces the jump/finish op to be the
last operation
- if node.provides_count() == 0:
- node.edge_to(jump_node, None, label='jump')
+ if node.depends_count() == 0:
+ self.schedulable_nodes.insert(0, node)
+ if not we_are_translated():
+ assert self.schedulable_nodes[-1] == label_node
def guard_argument_protection(self, guard_node, tracker):
""" the parameters the guard protects are an indicator for
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
@@ -98,6 +98,11 @@
raise AssertionError("schedule failed cannot continue. possible
reason: cycle")
+ jump_node = self.graph.nodes[-1]
+ assert jump_node.getopnum() == rop.JUMP
+ self.sched_data.unpack_from_vector(jump_node.getoperation(), self)
+ oplist.append(jump_node.getoperation())
+
def vectorbox_outof_box(box, count=-1, size=-1, type='-'):
if box.type not in (FLOAT, INT):
raise AssertionError("cannot create vector box of type %s" %
(box.type))
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
@@ -97,6 +97,7 @@
if cycle is not None:
print "CYCLE found %s" % cycle
self.show_dot_graph(opt.dependency_graph, "early_exit_" +
self.test_name)
+ assert cycle is None
opt.schedule(False)
opt.unroll_loop_iterations(loop, unroll_factor)
opt.loop.operations = opt.get_newoperations()
@@ -1348,7 +1349,6 @@
guard_true(i22, descr=<ResumeGuardTrueDescr object at 0x7fc657d7bdc0>)
[p1, p0, p5, p6, p7, p12, p13, i14]
jump(p0, p1, p5, p6, p7, p12, p13, i31, i15, i16, i17, i18, i19, i20)
"""
- # schedule 885 -> ptype is non for raw_load?
opt = self.vectorize(self.parse_loop(trace))
self.debug_print_operations(opt.loop)
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
@@ -469,6 +469,7 @@
if sched_data is None:
sched_data = VecScheduleData(self.cpu.vector_register_size,
self.costmodel, self.orig_label_args)
+ self.dependency_graph.prepare_for_scheduling()
scheduler = Scheduler(self.dependency_graph, sched_data)
renamer = Renamer()
#
@@ -515,49 +516,34 @@
label_node = graph.getnode(0)
ee_guard_node = graph.getnode(ee_pos)
guards = graph.guards
- unique = set()
for guard_node in guards:
if guard_node is ee_guard_node:
continue
modify_later = []
last_prev_node = None
- for path in guard_node.iterate_paths(ee_guard_node,
backwards=True, blacklist=True):
- p = '->'.join([str(p.opidx) for p in path.path])
- if p in unique:
- assert 0
+ valid = True
+ for prev_dep in guard_node.depends():
+ prev_node = prev_dep.to
+ if prev_dep.is_failarg():
+ # remove this edge later.
+ # 1) only because of failing, this dependency exists
+ # 2) non pure operation points to this guard.
+ # but if this guard only depends on pure operations, it
can be checked
+ # at an earlier position, the non pure op can execute
later!
+ modify_later.append((prev_node, guard_node))
else:
- unique.add(p)
- print "PATH:", p
- if not we_are_translated():
- path.check_acyclic()
- prev_node = path.second()
- dep = prev_node.depends_on(guard_node)
- if dep.is_failarg():
- # this dependency we are able to break because it is soley
- # relevant due to one or multiple fail args
- if prev_node is not last_prev_node:
- # ...
- # o o
- # \ /
- # (a)
- # |
- # (g)
- # this graph yields 2 paths from (g), thus (a) is
- # remembered and skipped the second time visited
- modify_later.append((prev_node, guard_node))
- print " => remove guard -> second"
- last_prev_node = prev_node
- continue
- if path.is_always_pure(exclude_first=True, exclude_last=True):
- path.set_schedule_priority(10)
- if path.last() is ee_guard_node:
- modify_later.append((path.last_but_one(), None))
- print " => always pure"
- else:
- # transformation is invalid.
- # exit and do not enter else branch!
- break
- else:
+ for path in prev_node.iterate_paths(ee_guard_node,
backwards=True, blacklist=True):
+ if path.is_always_pure(exclude_first=True,
exclude_last=True):
+ path.set_schedule_priority(10)
+ if path.last() is ee_guard_node:
+ modify_later.append((path.last_but_one(),
None))
+ else:
+ # transformation is invalid.
+ # exit and do not enter else branch!
+ valid = False
+ if not valid:
+ break
+ if valid:
# transformation is valid, modify the graph and execute
# this guard earlier
for a,b in modify_later:
@@ -568,7 +554,8 @@
if last_but_one is ee_guard_node:
continue
ee_guard_node.remove_edge_to(last_but_one)
- label_node.edge_to(last_but_one, label='pullup')
+ #label_node.edge_to(last_but_one, label='pullup')
+ print "guard", guard_node, "moved earlier"
# only the last guard needs a connection
guard_node.edge_to(ee_guard_node, label='pullup-last-guard')
self.relax_guard_to(guard_node, ee_guard_node)
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit