Author: Richard Plangger <[email protected]>
Branch: vecopt-merge
Changeset: r79738:275b9b40d178
Date: 2015-09-21 14:59 +0200
http://bitbucket.org/pypy/pypy/changeset/275b9b40d178/
Log: guard.py tests passing again
diff --git a/rpython/jit/metainterp/optimizeopt/guard.py
b/rpython/jit/metainterp/optimizeopt/guard.py
--- a/rpython/jit/metainterp/optimizeopt/guard.py
+++ b/rpython/jit/metainterp/optimizeopt/guard.py
@@ -82,16 +82,14 @@
opnum = self.transitive_cmpop(self.cmp_op.getopnum())
box_rhs = self.emit_varops(opt, self.rhs, self.cmp_op.getarg(1))
other_rhs = self.emit_varops(opt, other.rhs, other.cmp_op.getarg(1))
- box_result = self.cmp_op.result.clonebox()
- opt.emit_operation(ResOperation(opnum, [box_rhs, other_rhs],
box_result))
+ compare = ResOperation(opnum, [box_rhs, other_rhs])
+ opt.emit_operation(compare)
# guard
- guard = self.op.clone()
- descr = guard.getdescr()
+ descr = CompileLoopVersionDescr()
+ descr.copy_all_attributes_from(self.op.getdescr())
assert isinstance(descr, ResumeGuardDescr)
- guard.setdescr(descr.clone())
- guard.setarg(0, box_result)
- label = loop.find_first(rop.LABEL)
- guard.setfailargs(label.getarglist()[:])
+ guard = ResOperation(self.op.getopnum(), [compare], descr=descr)
+ guard.setfailargs(loop.label.getarglist_copy())
opt.emit_operation(guard)
return guard
@@ -146,12 +144,12 @@
self.setoperation(guard)
self.setcmp(cmp_op)
- def set_to_none(self, loop):
+ def set_to_none(self, info, loop):
operations = loop.operations
assert operations[self.index] is self.op
operations[self.index] = None
descr = self.op.getdescr()
- loop.version_info.remove(descr)
+ # TODO loop.version_info.remove(descr)
#if descr and descr.loop_version():
# assert isinstance(descr, CompileLoopVersionDescr)
# descr.version = None
@@ -280,21 +278,22 @@
#if not op.is_always_pure():
self._newoperations.append(op)
- def delay(self, op):
- self.delayed[op] = None
- print "delayed", op
+ # delay the pure ops
+ #def delay(self, op):
+ # self.delayed[op] = None
+ # print "delayed", op
- def emit_delayed_for(self, op):
- if op.is_inputarg():
- return
- additional = []
- if op.is_guard():
- additional = op.getfailargs()
- for arg in op.getarglist() + additional:
- if arg in self.delayed:
- del self.delayed[arg]
- self.emit_delayed_for(arg)
- self._newoperations.append(op)
+ #def emit_delayed_for(self, op):
+ # if op.is_inputarg():
+ # return
+ # additional = []
+ # if op.is_guard():
+ # additional = op.getfailargs()
+ # for arg in op.getarglist() + additional:
+ # if arg in self.delayed:
+ # del self.delayed[arg]
+ # self.emit_delayed_for(arg)
+ # self._newoperations.append(op)
def operation_position(self):
@@ -315,18 +314,21 @@
transitive_guard = one.transitive_imply(other, self, loop)
if transitive_guard:
if version is None:
- version = loop.snapshot()
- other.set_to_none(loop)
+ version = info.snapshot(loop)
+ other.set_to_none(info, loop)
descr = transitive_guard.getdescr()
assert isinstance(descr, ResumeGuardDescr)
info.track(transitive_guard, descr, version)
info.clear()
- if self.has_two_labels:
- oplist = [loop.operations[0]] + self._newoperations + \
- [op for op in loop.operations[1:] if op]
- loop.operations = oplist
- else:
- loop.operations = self._newoperations + \
- [op for op in loop.operations if op]
+ loop.prefix += self._newoperations
+ loop.operations = [op for op in loop.operations if op]
+ # TODO if self.has_two_labels:
+ # TODO oplist = [loop.operations[0]] + self._newoperations + \
+ # TODO [op for op in loop.operations[1:] if op]
+ # TODO loop.operations = oplist
+ # TODO else:
+ # TODO loop.operations = self._newoperations + \
+ # TODO [op for op in loop.operations if op]
+
diff --git a/rpython/jit/metainterp/optimizeopt/test/test_dependency.py
b/rpython/jit/metainterp/optimizeopt/test/test_dependency.py
--- a/rpython/jit/metainterp/optimizeopt/test/test_dependency.py
+++ b/rpython/jit/metainterp/optimizeopt/test/test_dependency.py
@@ -36,11 +36,12 @@
def build_dependency(self, ops):
loop = self.parse_loop(ops)
- self.last_graph = DependencyGraph(loop)
- self.show_dot_graph(self.last_graph, self.test_name)
- for node in self.last_graph.nodes:
+ graph = DependencyGraph(loop)
+ self.show_dot_graph(graph, self.test_name)
+ for node in graph.nodes:
assert node.independent(node)
- return self.last_graph
+ graph.parsestr = ops
+ return graph
def parse_loop(self, ops, add_label=True):
loop = self.parse(ops, postprocess=self.postprocess)
@@ -116,12 +117,11 @@
"dependencies unexpected %s.\n%s" \
% (dependencies,graph)
- def assert_dependencies(self, ops, full_check=True):
- graph = self.build_dependency(ops)
+ def assert_dependencies(self, graph, full_check=True):
import re
deps = {}
exceptions = {}
- for i,line in enumerate(ops.splitlines()):
+ for i,line in enumerate(graph.parsestr.splitlines()):
dep_pattern = re.compile("#\s*(\d+):")
dep_match = dep_pattern.search(line)
if dep_match:
@@ -142,18 +142,18 @@
self.assert_edges(graph, edges, exceptions)
return graph
- def assert_independent(self, a, b):
+ def assert_independent(self, graph, a, b):
a -= 1
b -= 1
- a = self.last_graph.getnode(a)
- b = self.last_graph.getnode(b)
+ a = graph.getnode(a)
+ b = graph.getnode(b)
assert a.independent(b), "{a} and {b} are dependent!".format(a=a,b=b)
- def assert_dependent(self, a, b):
+ def assert_dependent(self, graph, a, b):
a -= 1
b -= 1
- a = self.last_graph.getnode(a)
- b = self.last_graph.getnode(b)
+ a = graph.getnode(a)
+ b = graph.getnode(b)
assert not a.independent(b), "{a} and {b} are
independent!".format(a=a,b=b)
def show_dot_graph(self, graph, name):
@@ -237,82 +237,82 @@
assert m1.alias(m2) == alias
def test_dependency_empty(self):
- ops = """
+ graph = self.build_dependency("""
[] # 0: 1
jump() # 1:
- """
- self.assert_dependencies(ops, full_check=True)
+ """)
+ self.assert_dependencies(graph, full_check=True)
def test_dependency_of_constant_not_used(self):
- ops = """
+ graph = self.build_dependency("""
[] # 0: 2
i1 = int_add(1,1) # 1: 2
jump() # 2:
- """
- self.assert_dependencies(ops, full_check=True)
+ """)
+ self.assert_dependencies(graph, full_check=True)
def test_dependency_simple(self):
- ops = """
+ graph = self.build_dependency("""
[] # 0: 4
i1 = int_add(1,1) # 1: 2
i2 = int_add(i1,1) # 2: 3
guard_value(i2,3) [] # 3: 4
jump() # 4:
- """
- graph = self.assert_dependencies(ops, full_check=True)
+ """)
+ graph = self.assert_dependencies(graph, full_check=True)
self.assert_dependent(graph, 1,2)
self.assert_dependent(graph, 2,3)
self.assert_dependent(graph, 1,3)
def test_def_use_jump_use_def(self):
- ops = """
+ graph = self.build_dependency("""
[i3] # 0: 1
i1 = int_add(i3,1) # 1: 2, 3
guard_value(i1,0) [] # 2: 3
jump(i1) # 3:
- """
- self.assert_dependencies(ops, full_check=True)
+ """)
+ self.assert_dependencies(graph, full_check=True)
def test_dependency_guard(self):
- ops = """
+ graph = self.build_dependency("""
[i3] # 0: 2,3
i1 = int_add(1,1) # 1: 2
guard_value(i1,0) [i3] # 2: 3
jump(i3) # 3:
- """
- self.assert_dependencies(ops, full_check=True)
+ """)
+ self.assert_dependencies(graph, full_check=True)
def test_dependency_guard_2(self):
- ops = """
+ graph = self.build_dependency("""
[i1] # 0: 1,2?,3
i2 = int_le(i1, 10) # 1: 2
guard_true(i2) [i1] # 2:
i3 = int_add(i1,1) # 3: 4
jump(i3) # 4:
- """
- self.assert_dependencies(ops, full_check=True)
+ """)
+ self.assert_dependencies(graph, full_check=True)
def test_no_edge_duplication(self):
- ops = """
+ graph = self.build_dependency("""
[i1] # 0: 1,2?,3
i2 = int_lt(i1,10) # 1: 2
guard_false(i2) [i1] # 2:
i3 = int_add(i1,i1) # 3: 4
jump(i3) # 4:
- """
- self.assert_dependencies(ops, full_check=True)
+ """)
+ self.assert_dependencies(graph, full_check=True)
def test_no_edge_duplication_in_guard_failargs(self):
- ops = """
+ graph = self.build_dependency("""
[i1] # 0: 1,2?,3?
i2 = int_lt(i1,10) # 1: 2
guard_false(i2) [i1,i1,i2,i1,i2,i1] # 2: 3
jump(i1) # 3:
- """
- self.assert_dependencies(ops, full_check=True)
+ """)
+ self.assert_dependencies(graph, full_check=True)
def test_dependencies_1(self):
- ops="""
+ graph = self.build_dependency("""
[i0, i1, i2] # 0: 1,3,6,7,11?
i4 = int_gt(i1, 0) # 1: 2
guard_true(i4) [] # 2: 5, 11?
@@ -325,62 +325,62 @@
i16 = int_gt(i12, 0) # 9: 10
guard_true(i16) [] # 10: 11
jump(i12, i1, i14) # 11:
- """
- self.assert_dependencies(ops, full_check=True)
- self.assert_independent(6, 2)
- self.assert_independent(6, 1)
+ """)
+ self.assert_dependencies(graph, full_check=True)
+ self.assert_independent(graph, 6, 2)
+ self.assert_independent(graph, 6, 1)
def test_prevent_double_arg(self):
- ops="""
+ graph = self.build_dependency("""
[i0, i1, i2] # 0: 1,3
i4 = int_gt(i1, i0) # 1: 2
guard_true(i4) [] # 2: 3
jump(i0, i1, i2) # 3:
- """
- self.assert_dependencies(ops, full_check=True)
+ """)
+ self.assert_dependencies(graph, full_check=True)
def test_ovf_dep(self):
- ops="""
+ graph = self.build_dependency("""
[i0, i1, i2] # 0: 2,3
i4 = int_sub_ovf(1, 0) # 1: 2
guard_overflow() [i2] # 2: 3
jump(i0, i1, i2) # 3:
- """
- self.assert_dependencies(ops, full_check=True)
+ """)
+ self.assert_dependencies(graph, full_check=True)
def test_exception_dep(self):
- ops="""
+ graph = self.build_dependency("""
[p0, i1, i2] # 0: 1,3?
i4 = call_i(p0, 1, descr=nonwritedescr) # 1: 2,3
guard_no_exception() [] # 2: 3
jump(p0, i1, i2) # 3:
- """
- self.assert_dependencies(ops, full_check=True)
+ """)
+ self.assert_dependencies(graph, full_check=True)
def test_call_dependency_on_ptr_but_not_index_value(self):
- ops="""
+ graph = self.build_dependency("""
[p0, p1, i2] # 0: 1,2?,3?,4?,5?
i3 = int_add(i2,1) # 1: 2
i4 = call_i(p0, i3, descr=nonwritedescr) # 2: 3,4,5?
guard_no_exception() [i2] # 3:
p2 = getarrayitem_gc_r(p1, i3, descr=arraydescr) # 4: 5
jump(p2, p1, i3) # 5:
- """
- self.assert_dependencies(ops, full_check=True)
+ """)
+ self.assert_dependencies(graph, full_check=True)
def test_call_dependency(self):
- ops="""
+ graph = self.build_dependency("""
[p0, p1, i2, i5] # 0: 1,2?,3?,4?,5?
i3 = int_add(i2,1) # 1: 2
i4 = call_i(i5, i3, descr=nonwritedescr) # 2: 3,4,5?
guard_no_exception() [i2] # 3: 5?
p2 = getarrayitem_gc_r(p1,i3,descr=chararraydescr) # 4: 5
jump(p2, p1, i3, i5) # 5:
- """
- self.assert_dependencies(ops, full_check=True)
+ """)
+ self.assert_dependencies(graph, full_check=True)
def test_call_not_forced_exception(self):
- ops="""
+ graph = self.build_dependency("""
[p0, p1, i2, i5] # 0: 1,2,4?,5,6
i4 = call_i(i5, i2, descr=nonwritedescr) # 1: 2,4,6
guard_not_forced() [i2] # 2: 3
@@ -388,47 +388,47 @@
i3 = int_add(i2,1) # 4: 5
p2 = getarrayitem_gc_r(p1,i3,descr=chararraydescr) # 5: 6
jump(p2, p1, i2, i5) # 6:
- """
- self.assert_dependencies(ops, full_check=True)
- assert self.last_graph.nodes[1].priority == 100
- assert self.last_graph.nodes[2].priority == 100
+ """)
+ self.assert_dependencies(graph, full_check=True)
+ assert graph.nodes[1].priority == 100
+ assert graph.nodes[2].priority == 100
def test_setarrayitem_dependency(self):
- ops="""
+ graph = self.build_dependency("""
[p0, i1] # 0: 1,2?,3?,4?
setarrayitem_raw(p0, i1, 1, descr=floatarraydescr) # 1: 2,3
i2 = getarrayitem_raw_i(p0, i1, descr=floatarraydescr) # 2: 4
setarrayitem_raw(p0, i1, 2, descr=floatarraydescr) # 3: 4
jump(p0, i2) # 4:
- """
- self.assert_dependencies(ops, full_check=True)
+ """)
+ self.assert_dependencies(graph, full_check=True)
def test_setarrayitem_alias_dependency(self):
# #1 depends on #2, i1 and i2 might alias, reordering would destroy
# coorectness
- ops="""
+ graph = self.build_dependency("""
[p0, i1, i2] # 0: 1,2?,3?
setarrayitem_raw(p0, i1, 1, descr=floatarraydescr) # 1: 2
setarrayitem_raw(p0, i2, 2, descr=floatarraydescr) # 2: 3
jump(p0, i1, i2) # 3:
- """
- self.assert_dependencies(ops, full_check=True)
+ """)
+ self.assert_dependencies(graph, full_check=True)
self.assert_dependent(graph, 1,2)
def test_setarrayitem_dont_depend_with_memref_info(self):
- ops="""
+ graph = self.build_dependency("""
[p0, i1] # 0: 1,2,3?,4?
setarrayitem_raw(p0, i1, 1, descr=chararraydescr) # 1: 4
i2 = int_add(i1,1) # 2: 3
setarrayitem_raw(p0, i2, 2, descr=chararraydescr) # 3: 4
jump(p0, i1) # 4:
- """
- self.assert_dependencies(ops, full_check=True)
- self.assert_independent(1,2)
- self.assert_independent(1,3) # they modify 2 different cells
+ """)
+ self.assert_dependencies(graph, full_check=True)
+ self.assert_independent(graph, 1,2)
+ self.assert_independent(graph, 1,3) # they modify 2 different cells
def test_dependency_complex_trace(self):
- ops = """
+ graph = self.build_dependency("""
[i0, i1, i2, i3, i4, i5, i6, i7] # 0:
1,2,3,4,6,7,8,9,10,12,14,17,19,20,21
i9 = int_mul(i0, 8) # 1: 2
i10 = raw_load_i(i3, i9, descr=arraydescr) # 2: 5, 10
@@ -451,33 +451,32 @@
i25 = int_lt(i24, i7) # 19:
guard_true(i25) [i7, i22, i5, i4, i3, i21, i19, i24] # 20:
jump(i24, i19, i21, i3, i4, i5, i22, i7) # 21:
- """
- self.assert_dependencies(ops, full_check=False)
+ """)
+ self.assert_dependencies(graph, full_check=False)
self.assert_dependent(graph, 2,12)
def test_getfield(self):
- trace = """
+ graph = self.build_dependency("""
[p0, p1] # 0: 1,2,5
p2 = getfield_gc_r(p0) # 1: 3,5
p3 = getfield_gc_r(p0) # 2: 4
guard_nonnull(p2) [p2] # 3: 4,5
guard_nonnull(p3) [p3] # 4: 5
jump(p0,p2) # 5:
- """
- self.assert_dependencies(trace, full_check=True)
+ """)
+ self.assert_dependencies(graph, full_check=True)
def test_cyclic(self):
- trace = """
+ graph = self.build_dependency("""
[p0, p1, p5, p6, p7, p9, p11, p12] # 0: 1,6
- guard_early_exit() [] # 1:
- p13 = getfield_gc_r(p9) # 2: 3,5,6
- guard_nonnull(p13) [] # 3: 5,6
- i14 = getfield_gc_i(p9) # 4: 6
- p15 = getfield_gc_r(p13) # 5: 6
- guard_class(p15, 140737326900656) [p1, p0, p9, i14, p15, p13, p5, p6,
p7] # 6: 7
- jump(p0,p1,p5,p6,p7,p9,p11,p12) # 7:
- """
- self.assert_dependencies(trace, full_check=True)
+ p13 = getfield_gc_r(p9) # 1: 2,4,5
+ guard_nonnull(p13) [] # 2: 4,5
+ i14 = getfield_gc_i(p9) # 3: 5
+ p15 = getfield_gc_r(p13) # 4: 5
+ guard_class(p15, 140737326900656) [p1, p0, p9, i14, p15, p13, p5, p6,
p7] # 5: 6
+ jump(p0,p1,p5,p6,p7,p9,p11,p12) # 6:
+ """)
+ self.assert_dependencies(graph, full_check=True)
def test_iterate(self):
diff --git a/rpython/jit/metainterp/optimizeopt/test/test_guard.py
b/rpython/jit/metainterp/optimizeopt/test/test_guard.py
--- a/rpython/jit/metainterp/optimizeopt/test/test_guard.py
+++ b/rpython/jit/metainterp/optimizeopt/test/test_guard.py
@@ -13,8 +13,9 @@
from rpython.jit.metainterp.optimizeopt.test.test_util import LLtypeMixin
from rpython.jit.metainterp.optimizeopt.test.test_schedule import
SchedulerBaseTest
from rpython.jit.metainterp.optimizeopt.test.test_vecopt import
(FakeMetaInterpStaticData,
- FakeJitDriverStaticData)
-from rpython.jit.metainterp.resoperation import rop, ResOperation
+ FakeJitDriverStaticData, FakeLoopInfo)
+from rpython.jit.metainterp.resoperation import (rop,
+ ResOperation, InputArgInt)
from rpython.jit.tool.oparser_model import get_model
class FakeMemoryRef(object):
@@ -36,7 +37,7 @@
class FakeOp(object):
def __init__(self, cmpop):
- self.boolinverse = ResOperation(cmpop, [None, None], None).boolinverse
+ self.boolinverse = ResOperation(cmpop, [box(0), box(0)],
None).boolinverse
self.cmpop = cmpop
def getopnum(self):
@@ -80,19 +81,19 @@
class GuardBaseTest(SchedulerBaseTest):
def optguards(self, loop, user_code=False):
- #loop.snapshot()
+ info = FakeLoopInfo(loop)
+ info.snapshot(loop)
for op in loop.operations:
if op.is_guard():
op.setdescr(compile.CompileLoopVersionDescr())
dep = DependencyGraph(loop)
- opt = GuardStrengthenOpt(dep.index_vars, False)
- xxx
- opt.propagate_all_forward(loop, user_code)
+ opt = GuardStrengthenOpt(dep.index_vars)
+ opt.propagate_all_forward(info, loop, user_code)
return opt
def assert_guard_count(self, loop, count):
guard = 0
- for op in loop.operations:
+ for op in loop.operations + loop.prefix:
if op.is_guard():
guard += 1
if guard != count:
@@ -106,7 +107,8 @@
def __repr__(self):
return '*'
from rpython.jit.tool.oparser import OpParser, default_fail_descr
- parser = OpParser(instr, self.cpu, self.namespace(), 'lltype', None,
default_fail_descr, True, None)
+ parser = OpParser(instr, self.cpu, self.namespace, 'lltype', None,
default_fail_descr, False, None)
+ parser.vars = { arg.repr_short(arg._repr_memo) : arg for arg in
loop.inputargs}
operations = []
last_glob = None
prev_op = None
@@ -125,8 +127,6 @@
last_glob.next = op
last_glob = None
operations.append(op)
- prev_op = op
-
def check(op, candidate, rename):
m = 0
if isinstance(candidate, Glob):
@@ -144,14 +144,15 @@
else:
rename[arg] = oarg
- if op.result:
- rename[op.result] = candidate.result
+ if not op.returns_void():
+ rename[op] = candidate
m += 1
return m
return 0
j = 0
rename = {}
- for i, op in enumerate(loop.operations):
+ ops = loop.finaloplist()
+ for i, op in enumerate(ops):
candidate = operations[j]
j += check(op, candidate, rename)
if isinstance(operations[-1], Glob):
@@ -322,10 +323,10 @@
self.assert_guard_count(loop1, 2)
self.assert_contains_sequence(loop1, """
...
- i10 = int_gt(i1, 42)
+ i10 = int_ge(42, i2)
guard_true(i10) []
...
- i40 = int_gt(i11, i2)
+ i40 = int_gt(i1, 42)
guard_true(i40) []
...
""")
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
@@ -47,6 +47,14 @@
def operation_list(self):
return [self.label] + self.operations + [self.jump]
+ def finaloplist(self):
+ oplist = []
+ if self.prefix_label:
+ oplist = [self.prefix_label] + self.prefix
+ elif self.prefix:
+ oplist = self.prefix
+ return oplist + self.operations + [self.jump]
+
def assemble_oplist(self):
oplist = self.prefix + [self.prefix_label] + \
loop.operations + [loop.jump]
diff --git a/rpython/jit/metainterp/optimizeopt/version.py
b/rpython/jit/metainterp/optimizeopt/version.py
--- a/rpython/jit/metainterp/optimizeopt/version.py
+++ b/rpython/jit/metainterp/optimizeopt/version.py
@@ -39,7 +39,9 @@
def get(self, descr):
return self.leads_to.get(descr, None)
- def snapshot(self, operations, label):
+ def snapshot(self, loop):
+ operations = loop.finaloplist()
+ label = loop.label
oplist = []
ignore = (rop.DEBUG_MERGE_POINT,)
for op in operations:
diff --git a/rpython/jit/metainterp/resoperation.py
b/rpython/jit/metainterp/resoperation.py
--- a/rpython/jit/metainterp/resoperation.py
+++ b/rpython/jit/metainterp/resoperation.py
@@ -699,7 +699,7 @@
def same_shape(self, other):
""" NOT_RPYTHON """
- if not other.is_vector():
+ if other.is_vector() != self.is_vector():
return False
if self.datatype != other.datatype:
return False
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit