Author: Richard Plangger <[email protected]>
Branch: vecopt2
Changeset: r77108:f865517771a5
Date: 2015-04-09 11:53 +0200
http://bitbucket.org/pypy/pypy/changeset/f865517771a5/
Log: finished index variable tracking, added a new guard
(GUARD_NO_EARLY_EXIT)
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
@@ -772,6 +772,8 @@
resumedescr = ResumeGuardNotInvalidated()
elif opnum == rop.GUARD_FUTURE_CONDITION:
resumedescr = ResumeAtPositionDescr()
+ elif opnum == rop.GUARD_NO_EARLY_EXIT:
+ resumedescr = ResumeAtPositionDescr()
elif opnum == rop.GUARD_VALUE:
resumedescr = ResumeGuardValueDescr()
elif 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
@@ -72,7 +72,7 @@
while i >= 0:
def_index = def_chain[i][0]
oref = self.memory_refs.get(def_index)
- if oref is not None and not
mref.indices_can_alias(oref):
+ if oref is not None and mref.indices_can_alias(oref):
return def_index
elif oref is None:
return def_index
@@ -127,11 +127,12 @@
# the label operation defines all operations at the
# beginning of the loop
if op.getopnum() == rop.LABEL:
+ # TODO is it valid that a label occurs at the end of a trace?
for arg in op.getarglist():
tracker.define(arg, 0)
- if isinstance(arg, BoxInt):
- assert arg not in self.index_vars
- self.index_vars[arg] = IndexVar(arg)
+ #if isinstance(arg, BoxInt):
+ # assert arg not in self.index_vars
+ # self.index_vars[arg] = IndexVar(arg)
continue # prevent adding edge to the label itself
intformod.inspect_operation(op, i)
# definition of a new variable
@@ -194,9 +195,7 @@
def_idx = tracker.definition_index(var)
for dep in self.provides(def_idx):
if var in dep.args and dep.idx_to > guard_idx:
- #print "checking", var, "def at", def_idx, " -> ", dep
- #print " ==> yes"
- self._put_edge(guard_idx, dep.idx_to, var)
+ self._put_edge(guard_idx, dep.idx_to, var, force=True,
label='prev('+str(var)+')')
except KeyError:
pass
# handle fail args
@@ -205,8 +204,7 @@
for arg in op.getfailargs():
try:
for def_idx in tracker.redefintions(arg):
- self._put_edge(def_idx, guard_idx, arg)
- #print "put arg", arg, ":", def_idx, guard_idx,"!!!"
+ dep = self._put_edge(def_idx, guard_idx, arg,
label="fail")
except KeyError:
assert False
#
@@ -231,10 +229,10 @@
self._guard_inhert(prev_op_idx, guard_idx)
def _guard_inhert(self, idx, guard_idx):
- self._put_edge(idx, guard_idx, None)
+ dep = self._put_edge(idx, guard_idx, None, label='inhert')
for dep in self.provides(idx):
if dep.idx_to > guard_idx:
- self._put_edge(guard_idx, dep.idx_to, None)
+ self._put_edge(guard_idx, dep.idx_to, None, label='inhert')
def _build_non_pure_dependencies(self, op, index, tracker):
# self._update_memory_ref(op, index, tracker)
@@ -264,7 +262,7 @@
for dep in self.provides(def_idx):
if dep.idx_to >= index:
break
- self._put_edge(dep.idx_to, index, argcell)
+ self._put_edge(dep.idx_to, index, argcell,
label='war')
self._put_edge(def_idx, index, argcell)
except KeyError:
pass
@@ -331,17 +329,24 @@
else:
break # cannot go further, this might be the label, or a
constant
- def _put_edge(self, idx_from, idx_to, arg):
+ def _put_edge(self, idx_from, idx_to, arg, force=False, label=None):
assert idx_from != idx_to
dep = self.directly_depends(idx_from, idx_to)
if not dep:
- if self.independent(idx_from, idx_to):
+ if force or self.independent(idx_from, idx_to):
dep = Dependency(idx_from, idx_to, arg)
self.adjacent_list[idx_from].append(dep)
self.adjacent_list[idx_to].append(dep)
+ if not we_are_translated() and label is not None:
+ dep.label = label
else:
if arg not in dep.args:
dep.args.append(arg)
+ if not we_are_translated() and label is not None:
+ l = getattr(dep,'label',None)
+ if l is None:
+ l = ''
+ dep.label = l + ", " + label
def provides_count(self, idx):
i = 0
@@ -456,12 +461,18 @@
dot = "digraph dep_graph {\n"
for i in range(len(self.adjacent_list)):
op = operations[i]
- dot += " n%d [label=\"[%d]: %s\"];\n" % (i,i,str(op))
+ op_str = str(op)
+ if op.is_guard():
+ op_str += " " + str(op.getfailargs())
+ dot += " n%d [label=\"[%d]: %s\"];\n" % (i,i,op_str)
dot += "\n"
for i,alist in enumerate(self.adjacent_list):
for dep in alist:
if dep.idx_to > i:
- dot += " n%d -> n%d;\n" % (i,dep.idx_to)
+ label = ''
+ if getattr(dep, 'label', None):
+ label = '[label="%s"]' % dep.label
+ dot += " n%d -> n%d %s;\n" % (i,dep.idx_to,label)
dot += "\n}\n"
return dot
raise NotImplementedError("dot cannot built at runtime")
@@ -533,6 +544,12 @@
return True
return False
+ def get_or_create(self, arg):
+ var = self.index_vars.get(arg)
+ if not var:
+ var = self.index_vars[arg] = IndexVar(arg)
+ return var
+
additive_func_source = """
def operation_{name}(self, op, index):
box_r = op.result
@@ -545,15 +562,15 @@
idx_ref.constant = box_a0.getint() {op} box_a1.getint()
self.index_vars[box_r] = idx_ref
elif self.is_const_integral(box_a0):
- idx_ref = self.index_vars[box_a1]
+ idx_ref = self.get_or_create(box_a1)
+ idx_ref = idx_ref.clone()
+ idx_ref.constant {op}= box_a0.getint()
+ self.index_vars[box_r] = idx_ref
+ elif self.is_const_integral(box_a1):
+ idx_ref = self.get_or_create(box_a0)
idx_ref = idx_ref.clone()
idx_ref.constant {op}= box_a1.getint()
self.index_vars[box_r] = idx_ref
- elif self.is_const_integral(box_a1):
- idx_ref = self.index_vars[box_a0]
- idx_ref = idx_ref.clone()
- idx_ref.constant {op}= box_a0.getint()
- self.index_vars[box_r] = idx_ref
"""
exec py.code.Source(additive_func_source
.format(name='INT_ADD', op='+')).compile()
@@ -573,16 +590,16 @@
idx_ref.constant = box_a0.getint() {cop} box_a1.getint()
self.index_vars[box_r] = idx_ref
elif self.is_const_integral(box_a0):
- idx_ref = self.index_vars[box_a1]
+ idx_ref = self.get_or_create(box_a1)
idx_ref = idx_ref.clone()
- idx_ref.coefficient_{tgt} *= box_a1.getint()
- idx_ref.constant {cop}= box_a1.getint()
+ idx_ref.coefficient_{tgt} *= box_a0.getint()
+ idx_ref.constant {cop}= box_a0.getint()
self.index_vars[box_r] = idx_ref
elif self.is_const_integral(box_a1):
- idx_ref = self.index_vars[box_a0]
+ idx_ref = self.get_or_create(box_a0)
idx_ref = idx_ref.clone()
- idx_ref.coefficient_{tgt} {op}= box_a0.getint()
- idx_ref.constant {cop}= box_a0.getint()
+ idx_ref.coefficient_{tgt} {op}= box_a1.getint()
+ idx_ref.constant {cop}= box_a1.getint()
self.index_vars[box_r] = idx_ref
"""
exec py.code.Source(multiplicative_func_source
@@ -596,7 +613,7 @@
array_access_source = """
def operation_{name}(self, op, index):
descr = op.getdescr()
- idx_ref = self.index_vars[op.getarg(1)]
+ idx_ref = self.get_or_create(op.getarg(1))
self.memory_refs[index] = MemoryRef(op, idx_ref, {raw_access})
"""
exec py.code.Source(array_access_source
@@ -640,7 +657,6 @@
def same_variable(self, other):
assert isinstance(other, IndexVar)
- print other.var, "==", self.var, "?"
return other.var == self.var
def diff(self, other):
@@ -665,24 +681,24 @@
will result in the linear combination i0 * (2/1) + 2
"""
- def __init__(self, op, index_ref, raw_access=False):
+ def __init__(self, op, index_var, raw_access=False):
assert op.getdescr() is not None
self.array = op.getarg(0)
self.descr = op.getdescr()
- self.index_ref = index_ref
+ self.index_var = index_var
self.raw_access = raw_access
def is_adjacent_to(self, other):
""" this is a symmetric relation """
stride = self.stride()
if self.match(other):
- return abs(self.index_ref.diff(other.index_ref)) - stride == 0
+ return abs(self.index_var.diff(other.index_var)) - stride == 0
return False
def match(self, other):
assert isinstance(other, MemoryRef)
if self.array == other.array and self.descr == other.descr:
- return self.index_ref.same_variable(other.index_ref)
+ return self.index_var.same_variable(other.index_var)
return False
def stride(self):
@@ -695,7 +711,7 @@
""" the asymetric relation to is_adjacent_to """
stride = self.stride()
if self.match(other):
- return self.index_ref.diff(other.index_ref) == stride
+ return other.index_var.diff(self.index_var) == stride
return False
def indices_can_alias(self, other):
@@ -703,21 +719,22 @@
self.origin != other.origin, or their
linear combination point to the same element.
"""
- if not self.index_ref.same_variable(other.index_ref):
+ assert other is not None
+ if not self.index_var.same_variable(other.index_var):
return True
stride = self.stride()
if self.match(other):
- return not abs(self.index_ref.diff(other.index_ref)) < stride
- return True
+ diff = self.index_var.diff(other.index_var)
+ return abs(diff) < stride
+ return False
def __eq__(self, other):
if self.match(other):
- return self.index_ref.diff(other.index_ref) == 0
+ return self.index_var.diff(other.index_var) == 0
return False
def __ne__(self, other):
return not self.__eq__(other)
def __repr__(self):
- return 'MemRef(%s,%s*(%s/%s)+%s)' % (self.array, self.origin,
self.coefficient_mul,
- self.coefficient_div,
self.constant)
+ return 'MemRef(%s,%s)' % (self.array, self.index_var)
diff --git a/rpython/jit/metainterp/optimizeopt/simplify.py
b/rpython/jit/metainterp/optimizeopt/simplify.py
--- a/rpython/jit/metainterp/optimizeopt/simplify.py
+++ b/rpython/jit/metainterp/optimizeopt/simplify.py
@@ -65,6 +65,9 @@
def optimize_GUARD_FUTURE_CONDITION(self, op):
pass
+ def optimize_GUARD_NO_EARLY_EXIT(self, op):
+ pass
+
dispatch_opt = make_dispatcher_method(OptSimplify, 'optimize_',
default=OptSimplify.emit_operation)
OptSimplify.propagate_forward = dispatch_opt
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
@@ -24,7 +24,7 @@
def __str__(self):
return str(self.number)
-class DepTestHelper(BaseTest):
+class DependencyBaseTest(BaseTest):
def build_dependency(self, ops, refs = False):
loop = self.parse_loop(ops)
@@ -113,14 +113,31 @@
def _write_dot_and_convert_to_svg(self, graph, ops, filename):
dot = graph.as_dot(ops)
- print"gogogogog"
with open('/tmp/_'+filename+'.dot', 'w') as fd:
fd.write(dot)
with open('/tmp/'+filename+'.svg', 'w') as fd:
import subprocess
subprocess.Popen(['dot', '-Tsvg', '/tmp/_'+filename+'.dot'],
stdout=fd).communicate()
-class BaseTestDependencyGraph(DepTestHelper):
+ def debug_print_operations(self, loop):
+ print('--- loop instr numbered ---')
+ for i,op in enumerate(loop.operations):
+ print "[",i,"]",op,
+ if op.is_guard():
+ print op.rd_snapshot.boxes
+ else:
+ print ""
+
+ def assert_memory_ref_adjacent(self, m1, m2):
+ assert m1.is_adjacent_to(m2)
+ assert m2.is_adjacent_to(m1)
+
+ def assert_memory_ref_not_adjacent(self, m1, m2):
+ assert not m1.is_adjacent_to(m2)
+ assert not m2.is_adjacent_to(m1)
+
+
+class BaseTestDependencyGraph(DependencyBaseTest):
def test_dependency_empty(self):
ops = """
[] # 0: 1
@@ -299,7 +316,7 @@
def test_setarrayitem_depend_with_no_memref_info(self):
ops="""
[p0, i1] # 0: 1,2,3?,4?
- setarrayitem_raw(p0, i1, 1, descr=floatarraydescr) # 1: 3,4?
+ setarrayitem_raw(p0, i1, 1, descr=floatarraydescr) # 1: 4?
i2 = int_add(i1,1) # 2: 3
setarrayitem_raw(p0, i2, 2, descr=floatarraydescr) # 3: 4
jump(p0, i1) # 4:
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
@@ -3,7 +3,8 @@
from rpython.rlib.objectmodel import instantiate
from rpython.jit.metainterp.optimizeopt.test.test_util import (
- LLtypeMixin, BaseTest, FakeMetaInterpStaticData,
convert_old_style_to_targets)
+ LLtypeMixin, FakeMetaInterpStaticData, convert_old_style_to_targets)
+from rpython.jit.metainterp.optimizeopt.test.test_dependency import
DependencyBaseTest
from rpython.jit.metainterp.history import TargetToken, JitCellToken, TreeLoop
from rpython.jit.metainterp.optimizeopt import optimize_trace
import rpython.jit.metainterp.optimizeopt.optimizer as optimizeopt
@@ -21,12 +22,14 @@
class FakeJitDriverStaticData(object):
vectorize=True
-class VecTestHelper(BaseTest):
+class VecTestHelper(DependencyBaseTest):
enable_opts =
"intbounds:rewrite:virtualize:string:earlyforce:pure:heap:unfold"
+ jitdriver_sd = FakeJitDriverStaticData()
- jitdriver_sd = FakeJitDriverStaticData()
+ def setup_method(self, method):
+ self.test_name = method.__name__
def build_dependency(self, ops):
loop = self.parse_loop(ops)
@@ -50,86 +53,59 @@
self._do_optimize_loop(loop, call_pure_results, export_state=True)
self.assert_equal(loop, expected_loop)
- def vec_optimizer(self, loop):
+ def vectoroptimizer(self, loop):
metainterp_sd = FakeMetaInterpStaticData(self.cpu)
jitdriver_sd = FakeJitDriverStaticData()
opt = VectorizingOptimizer(metainterp_sd, jitdriver_sd, loop, [])
return opt
- def vec_optimizer_unrolled(self, loop, unroll_factor = -1):
- opt = self.vec_optimizer(loop)
- opt._gather_trace_information(loop)
+ def vectoroptimizer_unrolled(self, loop, unroll_factor = -1):
+ opt = self.vectoroptimizer(loop)
+ opt.linear_find_smallest_type(loop)
+ if unroll_factor == -1 and opt.smallest_type_bytes == 0:
+ raise NotAVectorizeableLoop()
if unroll_factor == -1:
unroll_factor = opt.get_unroll_count()
opt.unroll_loop_iterations(loop, unroll_factor)
opt.loop.operations = opt.get_newoperations()
+ opt.clear_newoperations()
+ opt.build_dependency_graph()
+ self.last_graph = opt.dependency_graph
return opt
def init_packset(self, loop, unroll_factor = -1):
- opt = self.vec_optimizer_unrolled(loop, unroll_factor)
- opt.build_dependency_graph()
+ opt = self.vectoroptimizer_unrolled(loop, unroll_factor)
opt.find_adjacent_memory_refs()
return opt
def extend_packset(self, loop, unroll_factor = -1):
- opt = self.vec_optimizer_unrolled(loop, unroll_factor)
- opt.build_dependency_graph()
+ opt = self.vectoroptimizer_unrolled(loop, unroll_factor)
self._write_dot_and_convert_to_svg(opt.dependency_graph,
opt.loop.operations, 'extend_packset')
opt.find_adjacent_memory_refs()
opt.extend_packset()
return opt
def combine_packset(self, loop, unroll_factor = -1):
- opt = self.vec_optimizer_unrolled(loop, unroll_factor)
- opt.build_dependency_graph()
+ opt = self.vectoroptimizer_unrolled(loop, unroll_factor)
opt.find_adjacent_memory_refs()
opt.extend_packset()
opt.combine_packset()
return opt
def schedule(self, loop, unroll_factor = -1):
- opt = self.vec_optimizer_unrolled(loop, unroll_factor)
- self.debug_print_operations(opt.loop)
- opt.build_dependency_graph()
+ opt = self.vectoroptimizer_unrolled(loop, unroll_factor)
opt.find_adjacent_memory_refs()
- self._write_dot_and_convert_to_svg(opt.dependency_graph,
opt.loop.operations, 'test')
+ self._write_dot_and_convert_to_svg(opt.dependency_graph,
opt.loop.operations, self.test_name)
opt.extend_packset()
opt.combine_packset()
opt.schedule()
return opt
- def _write_dot_and_convert_to_svg(self, graph, ops, filename):
- dot = graph.as_dot(ops)
- with open('/home/rich/' + filename + '.dot', 'w') as fd:
- fd.write(dot)
- with open('/home/rich/'+filename+'.svg', 'w') as fd:
- import subprocess
- subprocess.Popen(['dot', '-Tsvg', '/home/rich/'+filename+'.dot'],
stdout=fd).communicate()
-
def assert_unroll_loop_equals(self, loop, expected_loop, \
unroll_factor = -1):
- vec_optimizer = self.vec_optimizer_unrolled(loop, unroll_factor)
+ vectoroptimizer = self.vectoroptimizer_unrolled(loop, unroll_factor)
self.assert_equal(loop, expected_loop)
-
- def assert_memory_ref_adjacent(self, m1, m2):
- assert m1.is_adjacent_to(m2)
- assert m2.is_adjacent_to(m1)
-
- def assert_memory_ref_not_adjacent(self, m1, m2):
- assert not m1.is_adjacent_to(m2)
- assert not m2.is_adjacent_to(m1)
-
- def debug_print_operations(self, loop):
- print('--- loop instr numbered ---')
- for i,op in enumerate(loop.operations):
- print "[",i,"]",op,
- if op.is_guard():
- print op.rd_snapshot.boxes
- else:
- print ""
-
-
def assert_pack(self, pack, indices):
assert len(pack.operations) == len(indices)
for op,i in zip(pack.operations, indices):
@@ -146,7 +122,6 @@
else:
pytest.fail("could not find a packset that points to %s" %
str(opindices))
-
def assert_packset_empty(self, packset, instr_count, exceptions):
for a,b in exceptions:
self.assert_packset_contains_pair(packset, a, b)
@@ -174,29 +149,6 @@
pytest.fail("can't find a pack set for indices {x},{y}" \
.format(x=x,y=y))
- def assert_edges(self, graph, edge_list):
- """ Check if all dependencies are met. for complex cases
- adding None instead of a list of integers skips the test.
- This checks both if a dependency forward and backward exists.
- """
- assert len(edge_list) == len(graph.adjacent_list)
- for idx,edges in enumerate(edge_list):
- if edges is None:
- continue
- dependencies = graph.adjacent_list[idx][:]
- for edge in edges:
- dependency = graph.instr_dependency(idx,edge)
- if edge < idx:
- dependency = graph.instr_dependency(edge, idx)
- assert dependency is not None, \
- " it is expected that instruction at index" + \
- " %d depends on instr on index %d but it does not.\n%s" \
- % (idx, edge, graph)
- dependencies.remove(dependency)
- assert dependencies == [], \
- "dependencies unexpected %s.\n%s" \
- % (dependencies,graph)
-
class BaseTestVectorize(VecTestHelper):
def test_vectorize_skip_impossible_1(self):
@@ -291,8 +243,8 @@
raw_load(p0,i0,descr=arraydescr2)
jump(p0,i0)
"""
- vopt = self.vec_optimizer(self.parse_loop(ops))
- assert 0 == vopt.vec_info.smallest_type_bytes
+ vopt = self.vectoroptimizer(self.parse_loop(ops))
+ assert 0 == vopt.smallest_type_bytes
assert 0 == vopt.get_unroll_count()
def test_array_operation_indices_not_unrolled(self):
@@ -301,9 +253,10 @@
raw_load(p0,i0,descr=arraydescr2)
jump(p0,i0)
"""
- vopt = self.vec_optimizer_unrolled(self.parse_loop(ops))
- assert 1 in vopt.vec_info.memory_refs
- assert len(vopt.vec_info.memory_refs) == 1
+ vopt = self.vectoroptimizer_unrolled(self.parse_loop(ops),0)
+ vopt.build_dependency_graph()
+ assert 1 in vopt.dependency_graph.memory_refs
+ assert len(vopt.dependency_graph.memory_refs) == 1
def test_array_operation_indices_unrolled_1(self):
ops = """
@@ -311,10 +264,11 @@
raw_load(p0,i0,descr=chararraydescr)
jump(p0,i0)
"""
- vopt = self.vec_optimizer_unrolled(self.parse_loop(ops),1)
- assert 1 in vopt.vec_info.memory_refs
- assert 2 in vopt.vec_info.memory_refs
- assert len(vopt.vec_info.memory_refs) == 2
+ vopt = self.vectoroptimizer_unrolled(self.parse_loop(ops),1)
+ vopt.build_dependency_graph()
+ assert 1 in vopt.dependency_graph.memory_refs
+ assert 2 in vopt.dependency_graph.memory_refs
+ assert len(vopt.dependency_graph.memory_refs) == 2
def test_array_operation_indices_unrolled_2(self):
ops = """
@@ -323,18 +277,19 @@
i4 = raw_load(p0,i1,descr=chararraydescr)
jump(p0,i3,i4)
"""
- vopt = self.vec_optimizer_unrolled(self.parse_loop(ops),0)
- assert 1 in vopt.vec_info.memory_refs
- assert 2 in vopt.vec_info.memory_refs
- assert len(vopt.vec_info.memory_refs) == 2
- vopt = self.vec_optimizer_unrolled(self.parse_loop(ops),1)
+ vopt = self.vectoroptimizer_unrolled(self.parse_loop(ops),0)
+ vopt.build_dependency_graph()
+ assert 1 in vopt.dependency_graph.memory_refs
+ assert 2 in vopt.dependency_graph.memory_refs
+ assert len(vopt.dependency_graph.memory_refs) == 2
+ vopt = self.vectoroptimizer_unrolled(self.parse_loop(ops),1)
for i in [1,2,3,4]:
- assert i in vopt.vec_info.memory_refs
- assert len(vopt.vec_info.memory_refs) == 4
- vopt = self.vec_optimizer_unrolled(self.parse_loop(ops),3)
+ assert i in vopt.dependency_graph.memory_refs
+ assert len(vopt.dependency_graph.memory_refs) == 4
+ vopt = self.vectoroptimizer_unrolled(self.parse_loop(ops),3)
for i in [1,2,3,4,5,6,7,8]:
- assert i in vopt.vec_info.memory_refs
- assert len(vopt.vec_info.memory_refs) == 8
+ assert i in vopt.dependency_graph.memory_refs
+ assert len(vopt.dependency_graph.memory_refs) == 8
def test_array_memory_ref_adjacent_1(self):
ops = """
@@ -343,18 +298,17 @@
i1 = int_add(i0,1)
jump(p0,i1)
"""
- vopt = self.vec_optimizer_unrolled(self.parse_loop(ops),1)
- vopt.build_dependency_graph()
+ vopt = self.vectoroptimizer_unrolled(self.parse_loop(ops),1)
self.assert_edges(vopt.dependency_graph,
[ [1,2,3,5], [0,5], [0,3,4], [0,2,5], [2,5], [0,4,1,3] ])
vopt.find_adjacent_memory_refs()
- assert 1 in vopt.vec_info.memory_refs
- assert 3 in vopt.vec_info.memory_refs
- assert len(vopt.vec_info.memory_refs) == 2
+ assert 1 in vopt.dependency_graph.memory_refs
+ assert 3 in vopt.dependency_graph.memory_refs
+ assert len(vopt.dependency_graph.memory_refs) == 2
- mref1 = vopt.vec_info.memory_refs[1]
- mref3 = vopt.vec_info.memory_refs[3]
+ mref1 = vopt.dependency_graph.memory_refs[1]
+ mref3 = vopt.dependency_graph.memory_refs[3]
assert isinstance(mref1, MemoryRef)
assert isinstance(mref3, MemoryRef)
@@ -367,13 +321,12 @@
i3 = raw_load(p0,i0,descr=chararraydescr)
jump(p0,i0)
"""
- vopt = self.vec_optimizer_unrolled(self.parse_loop(ops),0)
- vopt.build_dependency_graph()
+ vopt = self.vectoroptimizer_unrolled(self.parse_loop(ops),0)
vopt.find_adjacent_memory_refs()
- mref1 = vopt.vec_info.memory_refs[1]
+ mref1 = vopt.dependency_graph.memory_refs[1]
assert isinstance(mref1, MemoryRef)
- assert mref1.coefficient_mul == 1
- assert mref1.constant == 0
+ assert mref1.index_var.coefficient_mul == 1
+ assert mref1.index_var.constant == 0
def test_array_memory_ref_2(self):
ops = """
@@ -382,13 +335,12 @@
i3 = raw_load(p0,i1,descr=chararraydescr)
jump(p0,i1)
"""
- vopt = self.vec_optimizer_unrolled(self.parse_loop(ops),0)
- vopt.build_dependency_graph()
+ vopt = self.vectoroptimizer_unrolled(self.parse_loop(ops),0)
vopt.find_adjacent_memory_refs()
- mref1 = vopt.vec_info.memory_refs[2]
+ mref1 = vopt.dependency_graph.memory_refs[2]
assert isinstance(mref1, MemoryRef)
- assert mref1.coefficient_mul == 1
- assert mref1.constant == 1
+ assert mref1.index_var.coefficient_mul == 1
+ assert mref1.index_var.constant == 1
def test_array_memory_ref_sub_index(self):
ops = """
@@ -397,13 +349,12 @@
i3 = raw_load(p0,i1,descr=chararraydescr)
jump(p0,i1)
"""
- vopt = self.vec_optimizer_unrolled(self.parse_loop(ops),0)
- vopt.build_dependency_graph()
+ vopt = self.vectoroptimizer_unrolled(self.parse_loop(ops),0)
vopt.find_adjacent_memory_refs()
- mref1 = vopt.vec_info.memory_refs[2]
+ mref1 = vopt.dependency_graph.memory_refs[2]
assert isinstance(mref1, MemoryRef)
- assert mref1.coefficient_mul == 1
- assert mref1.constant == -1
+ assert mref1.index_var.coefficient_mul == 1
+ assert mref1.index_var.constant == -1
def test_array_memory_ref_add_mul_index(self):
ops = """
@@ -413,13 +364,12 @@
i3 = raw_load(p0,i2,descr=chararraydescr)
jump(p0,i1)
"""
- vopt = self.vec_optimizer_unrolled(self.parse_loop(ops),0)
- vopt.build_dependency_graph()
+ vopt = self.vectoroptimizer_unrolled(self.parse_loop(ops),0)
vopt.find_adjacent_memory_refs()
- mref1 = vopt.vec_info.memory_refs[3]
+ mref1 = vopt.dependency_graph.memory_refs[3]
assert isinstance(mref1, MemoryRef)
- assert mref1.coefficient_mul == 3
- assert mref1.constant == 3
+ assert mref1.index_var.coefficient_mul == 3
+ assert mref1.index_var.constant == 3
def test_array_memory_ref_add_mul_index_interleaved(self):
ops = """
@@ -431,13 +381,12 @@
i5 = raw_load(p0,i4,descr=chararraydescr)
jump(p0,i4)
"""
- vopt = self.vec_optimizer_unrolled(self.parse_loop(ops),0)
- vopt.build_dependency_graph()
+ vopt = self.vectoroptimizer_unrolled(self.parse_loop(ops),0)
vopt.find_adjacent_memory_refs()
- mref1 = vopt.vec_info.memory_refs[5]
+ mref1 = vopt.dependency_graph.memory_refs[5]
assert isinstance(mref1, MemoryRef)
- assert mref1.coefficient_mul == 18
- assert mref1.constant == 48
+ assert mref1.index_var.coefficient_mul == 18
+ assert mref1.index_var.constant == 48
ops = """
[p0,i0]
@@ -450,14 +399,13 @@
i7 = raw_load(p0,i6,descr=chararraydescr)
jump(p0,i6)
"""
- vopt = self.vec_optimizer_unrolled(self.parse_loop(ops),0)
- vopt.build_dependency_graph()
+ vopt = self.vectoroptimizer_unrolled(self.parse_loop(ops),0)
vopt.find_adjacent_memory_refs()
- mref1 = vopt.vec_info.memory_refs[7]
+ mref1 = vopt.dependency_graph.memory_refs[7]
assert isinstance(mref1, MemoryRef)
- assert mref1.coefficient_mul == 1026
- assert mref1.coefficient_div == 1
- assert mref1.constant == 57*(30) + 57*6*(5) + 57*6*3*(1)
+ assert mref1.index_var.coefficient_mul == 1026
+ assert mref1.index_var.coefficient_div == 1
+ assert mref1.index_var.constant == 57*(30) + 57*6*(5) + 57*6*3*(1)
def test_array_memory_ref_sub_mul_index_interleaved(self):
ops = """
@@ -469,14 +417,13 @@
i5 = raw_load(p0,i4,descr=chararraydescr)
jump(p0,i4)
"""
- vopt = self.vec_optimizer_unrolled(self.parse_loop(ops),0)
- vopt.build_dependency_graph()
+ vopt = self.vectoroptimizer_unrolled(self.parse_loop(ops),0)
vopt.find_adjacent_memory_refs()
- mref1 = vopt.vec_info.memory_refs[5]
+ mref1 = vopt.dependency_graph.memory_refs[5]
assert isinstance(mref1, MemoryRef)
- assert mref1.coefficient_mul == 6
- assert mref1.coefficient_div == 1
- assert mref1.constant == 0
+ assert mref1.index_var.coefficient_mul == 6
+ assert mref1.index_var.coefficient_div == 1
+ assert mref1.index_var.constant == 0
def test_array_memory_ref_not_adjacent_1(self):
ops = """
@@ -500,8 +447,7 @@
jump(p0,i8,i7)
"""
- vopt = self.vec_optimizer_unrolled(self.parse_loop(ops),1)
- vopt.build_dependency_graph()
+ vopt = self.vectoroptimizer_unrolled(self.parse_loop(ops),1)
self.assert_edges(vopt.dependency_graph,
[ [1,2,3,4,5,7,9],
[0,9], [0,5,6], [0,9], [0,7,8],
@@ -512,13 +458,13 @@
vopt.find_adjacent_memory_refs()
for i in [1,3,5,7]:
- assert i in vopt.vec_info.memory_refs
- assert len(vopt.vec_info.memory_refs) == 4
+ assert i in vopt.dependency_graph.memory_refs
+ assert len(vopt.dependency_graph.memory_refs) == 4
- mref1 = vopt.vec_info.memory_refs[1]
- mref3 = vopt.vec_info.memory_refs[3]
- mref5 = vopt.vec_info.memory_refs[5]
- mref7 = vopt.vec_info.memory_refs[7]
+ mref1 = vopt.dependency_graph.memory_refs[1]
+ mref3 = vopt.dependency_graph.memory_refs[3]
+ mref5 = vopt.dependency_graph.memory_refs[5]
+ mref7 = vopt.dependency_graph.memory_refs[7]
assert isinstance(mref1, MemoryRef)
assert isinstance(mref3, MemoryRef)
assert isinstance(mref5, MemoryRef)
@@ -538,11 +484,10 @@
i3 = raw_load(p0,i2,descr=chararraydescr)
jump(p0,i2)
"""
- vopt = self.vec_optimizer_unrolled(self.parse_loop(ops),0)
- vopt.build_dependency_graph()
+ vopt = self.vectoroptimizer_unrolled(self.parse_loop(ops),0)
vopt.find_adjacent_memory_refs()
- mref = vopt.vec_info.memory_refs[3]
- assert mref.coefficient_div == 16
+ mref = vopt.dependency_graph.memory_refs[3]
+ assert mref.index_var.coefficient_div == 16
ops = """
[p0,i0]
i1 = int_add(i0,8)
@@ -550,12 +495,11 @@
i3 = raw_load(p0,i2,descr=chararraydescr)
jump(p0,i2)
"""
- vopt = self.vec_optimizer_unrolled(self.parse_loop(ops),0)
- vopt.build_dependency_graph()
+ vopt = self.vectoroptimizer_unrolled(self.parse_loop(ops),0)
vopt.find_adjacent_memory_refs()
- mref = vopt.vec_info.memory_refs[3]
- assert mref.coefficient_div == 2
- assert mref.constant == 4
+ mref = vopt.dependency_graph.memory_refs[3]
+ assert mref.index_var.coefficient_div == 2
+ assert mref.index_var.constant == 4
ops = """
[p0,i0]
i1 = int_add(i0,8)
@@ -566,11 +510,10 @@
i6 = raw_load(p0,i5,descr=chararraydescr)
jump(p0,i2)
"""
- vopt = self.vec_optimizer_unrolled(self.parse_loop(ops),0)
- vopt.build_dependency_graph()
+ vopt = self.vectoroptimizer_unrolled(self.parse_loop(ops),0)
vopt.find_adjacent_memory_refs()
- mref = vopt.vec_info.memory_refs[3]
- mref2 = vopt.vec_info.memory_refs[6]
+ mref = vopt.dependency_graph.memory_refs[3]
+ mref2 = vopt.dependency_graph.memory_refs[6]
self.assert_memory_ref_not_adjacent(mref, mref2)
assert mref != mref2
@@ -587,11 +530,10 @@
i7 = raw_load(p0,i6,descr=chararraydescr)
jump(p0,i2)
"""
- vopt = self.vec_optimizer_unrolled(self.parse_loop(ops),0)
- vopt.build_dependency_graph()
+ vopt = self.vectoroptimizer_unrolled(self.parse_loop(ops),0)
vopt.find_adjacent_memory_refs()
- mref = vopt.vec_info.memory_refs[3]
- mref2 = vopt.vec_info.memory_refs[7]
+ mref = vopt.dependency_graph.memory_refs[3]
+ mref2 = vopt.dependency_graph.memory_refs[7]
self.assert_memory_ref_not_adjacent(mref, mref2)
assert mref == mref2
@@ -608,11 +550,10 @@
i7 = raw_load(p0,i6,descr=chararraydescr)
jump(p0,i2)
"""
- vopt = self.vec_optimizer_unrolled(self.parse_loop(ops),0)
- vopt.build_dependency_graph()
+ vopt = self.vectoroptimizer_unrolled(self.parse_loop(ops),0)
vopt.find_adjacent_memory_refs()
- mref = vopt.vec_info.memory_refs[3]
- mref2 = vopt.vec_info.memory_refs[7]
+ mref = vopt.dependency_graph.memory_refs[3]
+ mref2 = vopt.dependency_graph.memory_refs[7]
self.assert_memory_ref_not_adjacent(mref, mref2)
assert mref != mref2
@@ -625,7 +566,7 @@
jump()
"""
loop = self.parse_loop(ops)
- vopt = self.vec_optimizer_unrolled(loop,1)
+ vopt = self.vectoroptimizer_unrolled(loop,1)
self.assert_equal(loop, self.parse_loop(ops))
def test_packset_init_simple(self):
@@ -641,7 +582,7 @@
vopt = self.init_packset(loop,1)
assert vopt.dependency_graph.independent(1,5)
assert vopt.packset is not None
- assert len(vopt.vec_info.memory_refs) == 2
+ assert len(vopt.dependency_graph.memory_refs) == 2
assert len(vopt.packset.packs) == 1
def test_packset_init_raw_load_not_adjacent_and_adjacent(self):
@@ -652,7 +593,7 @@
"""
loop = self.parse_loop(ops)
vopt = self.init_packset(loop,3)
- assert len(vopt.vec_info.memory_refs) == 4
+ assert len(vopt.dependency_graph.memory_refs) == 4
assert len(vopt.packset.packs) == 0
ops = """
[p0,i0]
@@ -662,8 +603,7 @@
"""
loop = self.parse_loop(ops)
vopt = self.init_packset(loop,3)
- assert len(vopt.vec_info.memory_refs) == 4
- print vopt.packset.packs
+ assert len(vopt.dependency_graph.memory_refs) == 4
assert len(vopt.packset.packs) == 3
for i in range(3):
x = (i+1)*2
@@ -682,19 +622,19 @@
"""
loop = self.parse_loop(ops)
vopt = self.init_packset(loop,15)
- assert len(vopt.vec_info.memory_refs) == 16
+ assert len(vopt.dependency_graph.memory_refs) == 16
assert len(vopt.packset.packs) == 15
# assure that memory refs are not adjacent for all
for i in range(15):
for j in range(15):
try:
if i-4 == j or i+4 == j:
- mref1 = vopt.vec_info.memory_refs[i]
- mref2 = vopt.vec_info.memory_refs[j]
+ mref1 = vopt.dependency_graph.memory_refs[i]
+ mref2 = vopt.dependency_graph.memory_refs[j]
assert mref1.is_adjacent_to(mref2)
else:
- mref1 = vopt.vec_info.memory_refs[i]
- mref2 = vopt.vec_info.memory_refs[j]
+ mref1 = vopt.dependency_graph.memory_refs[i]
+ mref2 = vopt.dependency_graph.memory_refs[j]
assert not mref1.is_adjacent_to(mref2)
except KeyError:
pass
@@ -739,7 +679,7 @@
"""
loop = self.parse_loop(ops)
vopt = self.extend_packset(loop,1)
- assert len(vopt.vec_info.memory_refs) == 2
+ assert len(vopt.dependency_graph.memory_refs) == 2
assert vopt.dependency_graph.independent(5,10) == True
assert len(vopt.packset.packs) == 2
self.assert_packset_empty(vopt.packset, len(loop.operations),
@@ -758,7 +698,7 @@
"""
loop = self.parse_loop(ops)
vopt = self.extend_packset(loop,1)
- assert len(vopt.vec_info.memory_refs) == 4
+ assert len(vopt.dependency_graph.memory_refs) == 4
assert vopt.dependency_graph.independent(4,10)
assert vopt.dependency_graph.independent(5,11)
assert vopt.dependency_graph.independent(6,12)
@@ -776,7 +716,7 @@
""".format(descr=descr)
loop = self.parse_loop(ops)
vopt = self.combine_packset(loop,3)
- assert len(vopt.vec_info.memory_refs) == 4
+ assert len(vopt.dependency_graph.memory_refs) == 4
assert len(vopt.packset.packs) == 1
self.assert_pack(vopt.packset.packs[0], (1,3,5,7))
ops = """
@@ -787,7 +727,7 @@
""".format(descr=descr)
loop = self.parse_loop(ops)
vopt = self.combine_packset(loop,3)
- assert len(vopt.vec_info.memory_refs) == 4
+ assert len(vopt.dependency_graph.memory_refs) == 4
assert len(vopt.packset.packs) == 1
self.assert_pack(vopt.packset.packs[0], (1,3,5,7))
@@ -804,10 +744,7 @@
""".format(type=descr,stride=stride)
loop = self.parse_loop(ops)
vopt = self.combine_packset(loop,3)
- assert len(vopt.vec_info.memory_refs) == 8
- print "---"
- for p in vopt.packset.packs:
- print p
+ assert len(vopt.dependency_graph.memory_refs) == 8
assert len(vopt.packset.packs) == 1
self.assert_pack(vopt.packset.packs[0], (1,3,5,7,9,11,13,15))
@@ -822,7 +759,7 @@
pytest.skip("loop unrolling must apply redundant loop unrolling")
loop = self.parse_loop(ops)
vopt = self.combine_packset(loop,3)
- assert len(vopt.vec_info.memory_refs) == 4
+ assert len(vopt.dependency_graph.memory_refs) == 4
assert len(vopt.packset.packs) == 1
self.assert_pack(vopt.packset.packs[0], (1,3,5,7))
@@ -877,7 +814,7 @@
""".format(op=op,descr=descr,stride=stride)
loop = self.parse_loop(ops)
vopt = self.combine_packset(loop,3)
- assert len(vopt.vec_info.memory_refs) == 12
+ assert len(vopt.dependency_graph.memory_refs) == 12
assert len(vopt.packset.packs) == 4
for opindices in [(4,11,18,25),(5,12,19,26),
@@ -926,7 +863,6 @@
""".format(op='vec_'+op,descr=descr,stride=1)
loop = self.parse_loop(ops)
vopt = self.schedule(loop,1)
- self.debug_print_operations(vopt.loop)
self.assert_equal(loop, self.parse_loop(vops))
@pytest.mark.parametrize('unroll', range(1,16,2))
@@ -965,12 +901,7 @@
guard_future_condition() []
jump(i16, i10, i12, i3, i4, i5, i13, i7)
"""
- self.debug_print_operations(self.parse_loop(ops))
vopt = self.schedule(self.parse_loop(ops),1)
- print "_--" * 10
- print vopt.vec_info.memory_refs
- print "_--" * 10
- self.debug_print_operations(vopt.loop)
def test_123(self):
ops = """
@@ -988,9 +919,8 @@
label(i11, i1, i2, i3, i4)
"""
vopt = self.schedule(self.parse_loop(ops),1)
- self.debug_print_operations(vopt.loop)
- def test_111(self):
+ def test_schedule_vectorized_trace_1(self):
ops = """
[i0, i1, i2, i3, i4, i5, i6, i7]
i8 = raw_load(i3, i0, descr=intarraydescr)
@@ -1002,10 +932,9 @@
i15 = int_lt(i12, i14)
guard_true(i15) [i7, i10, i5, i4, i3, i9, i8, i12]
guard_future_condition() []
- label(i12, i8, i9, i3, i4, i5, i10, i7)
+ jump(i12, i8, i9, i3, i4, i5, i10, i7)
"""
vopt = self.schedule(self.parse_loop(ops),1)
- self.debug_print_operations(vopt.loop)
class TestLLtype(BaseTestVectorize, LLtypeMixin):
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
@@ -10,6 +10,7 @@
from rpython.jit.metainterp.resume import Snapshot
from rpython.rlib.debug import debug_print, debug_start, debug_stop
from rpython.jit.metainterp.jitexc import JitException
+from rpython.rlib.objectmodel import we_are_translated
class NotAVectorizeableLoop(JitException):
def __str__(self):
@@ -73,6 +74,27 @@
self.unroll_count = 0
self.smallest_type_bytes = 0
+ def propagate_all_forward(self):
+ self.clear_newoperations()
+ self.linear_find_smallest_type(self.loop)
+ byte_count = self.smallest_type_bytes
+ if byte_count == 0:
+ # stop, there is no chance to vectorize this trace
+ raise NotAVectorizeableLoop()
+
+ # unroll
+ self.unroll_count = self.get_unroll_count()
+ self.unroll_loop_iterations(self.loop, self.unroll_count)
+ self.loop.operations = self.get_newoperations();
+ self.clear_newoperations();
+
+ # vectorize
+ self.build_dependency_graph()
+ self.find_adjacent_memory_refs()
+ self.extend_packset()
+ self.combine_packset()
+ self.schedule()
+
def emit_operation(self, op):
self._last_emitted_op = op
self._newoperations.append(op)
@@ -149,8 +171,18 @@
# to be adjusted. rd_snapshot stores the live variables
# that are needed to resume.
if copied_op.is_guard():
- copied_op.rd_snapshot = \
- self.clone_snapshot(copied_op.rd_snapshot, rename_map)
+ snapshot = self.clone_snapshot(copied_op.rd_snapshot,
rename_map)
+ copied_op.rd_snapshot = snapshot
+ if not we_are_translated():
+ # ensure that in a test case the renaming is correct
+ args = copied_op.getfailargs()[:]
+ for i,arg in enumerate(args):
+ try:
+ value = rename_map[arg]
+ args[i] = value
+ except KeyError:
+ pass
+ copied_op.setfailargs(args)
#
self.emit_unrolled_operation(copied_op)
#self.vec_info.index = len(self._newoperations)-1
@@ -182,9 +214,7 @@
try:
value = rename_map[box]
new_boxes[i] = value
- print "box", box, "=>", value
except KeyError:
- print "FAIL:", i, box
pass
snapshot = Snapshot(self.clone_snapshot(snapshot.prev, rename_map),
@@ -212,29 +242,9 @@
unroll_count = simd_vec_reg_bytes // byte_count
return unroll_count-1 # it is already unrolled once
- def propagate_all_forward(self):
-
- self.clear_newoperations()
-
- self.linear_find_smallest_type(self.loop)
-
- byte_count = self.smallest_type_bytes
- if byte_count == 0:
- # stop, there is no chance to vectorize this trace
- raise NotAVectorizeableLoop()
-
- self.unroll_count = self.get_unroll_count()
-
- self.unroll_loop_iterations(self.loop, self.unroll_count)
-
- self.loop.operations = self.get_newoperations();
- self.clear_newoperations();
-
- self.build_dependency_graph()
- self.find_adjacent_memory_refs()
- self.extend_packset()
- self.combine_packset()
- self.schedule()
+ def build_dependency_graph(self):
+ self.dependency_graph = DependencyGraph(self.loop.operations)
+ self.relax_guard_dependencies()
def relax_guard_dependencies(self):
return
@@ -243,17 +253,7 @@
for dep in self.dependency_graph.depends(idx):
op = self.operations[dep.idx_from]
if op.returns_bool_result():
- for arg in op.getarglist():
- if isinstance(arg, Box):
- self._track_integral_modification(arg)
-
- def _track_integral_modification(self, arg):
- ref = MemoryRef(None, arg, None)
-
- def build_dependency_graph(self):
- self.dependency_graph = \
- DependencyGraph(self.loop.operations)
- self.relax_guard_dependencies()
+ pass
def find_adjacent_memory_refs(self):
""" the pre pass already builds a hash of memory references and the
@@ -267,8 +267,8 @@
self.packset = PackSet(self.dependency_graph, operations,
self.unroll_count,
- self.vec_info.smallest_type_bytes)
- memory_refs = self.vec_info.memory_refs.items()
+ self.smallest_type_bytes)
+ memory_refs = self.dependency_graph.memory_refs.items()
# initialize the pack set
for a_opidx,a_memref in memory_refs:
for b_opidx,b_memref in memory_refs:
@@ -339,7 +339,6 @@
end_ij = len(self.packset.packs)
while True:
len_before = len(self.packset.packs)
- print "loop", len_before
i = 0
while i < end_ij:
while j < end_ij and i < end_ij:
@@ -529,15 +528,15 @@
return -1
if not expand_forward:
- print " backward savings", savings
+ #print " backward savings", savings
if not must_unpack_result_to_exec(target_op, lop):
savings += 1
- print " => backward savings", savings
+ #print " => backward savings", savings
else:
- print " forward savings", savings
+ #print " forward savings", savings
if not must_unpack_result_to_exec(target_op, lop):
savings += 1
- print " => forward savings", savings
+ #print " => forward savings", savings
return savings
diff --git a/rpython/jit/metainterp/pyjitpl.py
b/rpython/jit/metainterp/pyjitpl.py
--- a/rpython/jit/metainterp/pyjitpl.py
+++ b/rpython/jit/metainterp/pyjitpl.py
@@ -2133,6 +2133,7 @@
self.resumekey = compile.ResumeFromInterpDescr(original_greenkey)
self.history.inputargs = original_boxes[num_green_args:]
self.seen_loop_header_for_jdindex = -1
+ self.generate_guard(rop.GUARD_NO_EARLY_EXIT)
try:
self.interpret()
except SwitchToBlackhole, stb:
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
@@ -418,6 +418,7 @@
'GUARD_NOT_FORCED/0d', # may be called with an exception currently set
'GUARD_NOT_FORCED_2/0d', # same as GUARD_NOT_FORCED, but for finish()
'GUARD_NOT_INVALIDATED/0d',
+ 'GUARD_NO_EARLY_EXIT/0d', # is removable, may be patched by an optimization
'GUARD_FUTURE_CONDITION/0d', # is removable, may be patched by an
optimization
'_GUARD_LAST', # ----- end of guard operations -----
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit