Author: Richard Plangger <[email protected]>
Branch: vecopt2
Changeset: r77131:ce46889cad5d
Date: 2015-05-04 15:16 +0200
http://bitbucket.org/pypy/pypy/changeset/ce46889cad5d/
Log: bridge can now be assembled (previously an early exit skipped to the
blackhole interpreter) added a test case to test a vector that is
too small
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
@@ -836,13 +836,14 @@
new_trace.operations = metainterp.history.operations[:]
metainterp_sd = metainterp.staticdata
jitdriver_sd = metainterp.jitdriver_sd
- state = jitdriver_sd.warmstate
- if isinstance(resumekey, ResumeAtPositionDescr):
+ warmstate = jitdriver_sd.warmstate
+ if isinstance(resumekey, ResumeAtPositionDescr) or \
+ isinstance(resumekey, ResumeAtLoopHeaderDescr):
inline_short_preamble = False
else:
inline_short_preamble = True
try:
- state = optimize_trace(metainterp_sd, jitdriver_sd, new_trace, state,
+ state = optimize_trace(metainterp_sd, jitdriver_sd, new_trace,
warmstate,
inline_short_preamble, export_state=True)
except InvalidLoop:
debug_print("compile_new_bridge: got an InvalidLoop")
diff --git a/rpython/jit/metainterp/optimizeopt/__init__.py
b/rpython/jit/metainterp/optimizeopt/__init__.py
--- a/rpython/jit/metainterp/optimizeopt/__init__.py
+++ b/rpython/jit/metainterp/optimizeopt/__init__.py
@@ -69,7 +69,8 @@
optimizations, unroll = build_opt_chain(metainterp_sd, enable_opts)
if unroll:
if not export_state and warmstate.vectorize and
jitdriver_sd.vectorize:
- optimize_vector(metainterp_sd, jitdriver_sd, loop,
optimizations)
+ optimize_vector(metainterp_sd, jitdriver_sd, loop,
optimizations,
+ inline_short_preamble, start_state)
else:
return optimize_unroll(metainterp_sd, jitdriver_sd, loop,
optimizations, inline_short_preamble,
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
@@ -116,13 +116,19 @@
op = guard.getoperation()
assert isinstance(tgt_op, GuardResOp)
assert isinstance(op, GuardResOp)
- #descr = compile.ResumeAtLoopHeaderDescr()
+ olddescr = tgt_op.getdescr()
descr = compile.ResumeAtLoopHeaderDescr()
+ descr.rd_consts = olddescr.rd_consts
+ descr.rd_pendingfields = olddescr.rd_pendingfields
+ descr.rd_virtuals = olddescr.rd_virtuals
+ descr.rd_numb = olddescr.rd_numb
+ descr.rd_count = olddescr.rd_count
+ descr.rd_frame_info_list = olddescr.rd_frame_info_list
+ #
tgt_op.setdescr(descr)
- if not we_are_translated():
- tgt_op.setfailargs(op.getfailargs())
tgt_op.rd_snapshot = op.rd_snapshot
- tgt_op.rd_frame_info_list = op.rd_frame_info_list
+ #if not we_are_translated():
+ tgt_op.setfailargs(op.getfailargs())
def edge_to(self, to, arg=None, label=None):
assert self != to
@@ -360,12 +366,14 @@
self.defs = {}
def define(self, arg, node, argcell=None):
+ if isinstance(arg, Const):
+ return
if arg in self.defs:
self.defs[arg].append((node,argcell))
else:
self.defs[arg] = [(node,argcell)]
- def redefintions(self, arg):
+ def redefinitions(self, arg):
for _def in self.defs[arg]:
yield _def[0]
@@ -424,8 +432,9 @@
modifications of one array even if the indices can never point to
the same element.
"""
- def __init__(self, operations):
- self.nodes = [ Node(op,i) for i,op in enumerate(operations) ]
+ def __init__(self, loop):
+ self.loop = loop
+ self.nodes = [ Node(op,i) for i,op in enumerate(loop.operations) ]
self.memory_refs = {}
self.schedulable_nodes = []
self.index_vars = {}
@@ -455,14 +464,16 @@
# the label operation defines all operations at the
# beginning of the loop
if op.getopnum() == rop.LABEL and i != jump_pos:
- # TODO is it valid that a label occurs at the end of a trace?
- ee_node = self.nodes[i+1]
- if ee_node.is_guard_early_exit():
- node.edge_to(ee_node,None,label='L->EE')
- node = ee_node
+ label_pos = i
for arg in op.getarglist():
tracker.define(arg, node)
continue # prevent adding edge to the label itself
+ elif node.is_guard_early_exit():
+ label_node = self.nodes[label_pos]
+ label_node.edge_to(node,None,label='L->EE')
+ for arg in label_node.getoperation().getarglist():
+ tracker.define(arg, node)
+ continue
intformod.inspect_operation(op,node)
# definition of a new variable
if op.result is not None:
@@ -529,9 +540,11 @@
if guard_op.getfailargs():
for arg in guard_op.getfailargs():
try:
- for at in tracker.redefintions(arg):
+ for at in tracker.redefinitions(arg):
# later redefinitions are prohibited
- if at.is_before(guard_node):
+ descr = guard_op.getdescr()
+ if at.is_before(guard_node) and \
+ not isinstance(descr,
compile.ResumeAtLoopHeaderDescr):
at.edge_to(guard_node, arg, label="fail")
except KeyError:
assert False
@@ -619,7 +632,7 @@
op = node.getoperation()
op_str = str(op)
if op.is_guard():
- op_str += " " + str(op.getfailargs())
+ op_str += " " + ','.join([str(arg) for arg in
op.getfailargs()])
dot += " n%d [label=\"[%d]: %s\"];\n" %
(node.getindex(),node.getindex(),op_str)
dot += "\n"
for node in self.nodes:
diff --git a/rpython/jit/metainterp/optimizeopt/rewrite.py
b/rpython/jit/metainterp/optimizeopt/rewrite.py
--- a/rpython/jit/metainterp/optimizeopt/rewrite.py
+++ b/rpython/jit/metainterp/optimizeopt/rewrite.py
@@ -559,9 +559,6 @@
def optimize_GUARD_FUTURE_CONDITION(self, op):
pass # just remove it
- def optimize_GUARD_EARLY_EXIT(self, op):
- pass # just remove it
-
def optimize_INT_FLOORDIV(self, op):
v1 = self.getvalue(op.getarg(0))
v2 = self.getvalue(op.getarg(1))
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,9 +65,6 @@
def optimize_GUARD_FUTURE_CONDITION(self, op):
pass
- def optimize_GUARD_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
@@ -15,7 +15,7 @@
def build_dependency(self, ops):
loop = self.parse_loop(ops)
- self.last_graph = DependencyGraph(loop.operations)
+ self.last_graph = DependencyGraph(loop)
self._write_dot_and_convert_to_svg(self.last_graph, self.test_name)
for node in self.last_graph.nodes:
assert node.independent(node)
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
@@ -1,7 +1,9 @@
-import sys
import py
+
+from rpython.jit.metainterp.resume import Snapshot
+from rpython.jit.metainterp.jitexc import JitException
+from rpython.jit.metainterp.optimizeopt.unroll import optimize_unroll
from rpython.jit.metainterp.compile import ResumeAtLoopHeaderDescr
-from rpython.rtyper.lltypesystem import lltype, rffi
from rpython.jit.metainterp.history import (ConstInt, VECTOR, BoxVector,
TargetToken, JitCellToken)
from rpython.jit.metainterp.optimizeopt.optimizer import Optimizer,
Optimization
@@ -9,10 +11,9 @@
from rpython.jit.metainterp.optimizeopt.dependency import (DependencyGraph,
MemoryRef, Scheduler, SchedulerData, Node)
from rpython.jit.metainterp.resoperation import (rop, ResOperation, GuardResOp)
-from rpython.jit.metainterp.resume import Snapshot
+from rpython.rlib.objectmodel import we_are_translated
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
+from rpython.rtyper.lltypesystem import lltype, rffi
class NotAVectorizeableLoop(JitException):
def __str__(self):
@@ -41,17 +42,16 @@
else:
print ""
-def optimize_vector(metainterp_sd, jitdriver_sd, loop, optimizations):
- opt = VectorizingOptimizer(metainterp_sd, jitdriver_sd, loop,
optimizations)
+def optimize_vector(metainterp_sd, jitdriver_sd, loop, optimizations,
+ inline_short_preamble, start_state):
+ optimize_unroll(metainterp_sd, jitdriver_sd, loop, optimizations,
+ inline_short_preamble, start_state, False)
try:
+ opt = VectorizingOptimizer(metainterp_sd, jitdriver_sd, loop,
optimizations)
opt.propagate_all_forward()
- #debug_print_operations(loop)
- def_opt = Optimizer(metainterp_sd, jitdriver_sd, loop, optimizations)
- def_opt.propagate_all_forward()
except NotAVectorizeableLoop:
# vectorization is not possible, propagate only normal optimizations
- def_opt = Optimizer(metainterp_sd, jitdriver_sd, loop, optimizations)
- def_opt.propagate_all_forward()
+ pass
#class CollapseGuardOptimization(Optimization):
# def __init__(self, index_vars = None):
@@ -99,6 +99,7 @@
self.loop.operations = self.get_newoperations();
self.clear_newoperations();
+ debug_print_operations(self.loop)
# vectorize
self.build_dependency_graph()
self.find_adjacent_memory_refs()
@@ -265,7 +266,7 @@
return unroll_count-1 # it is already unrolled once
def build_dependency_graph(self):
- self.dependency_graph = DependencyGraph(self.loop.operations)
+ self.dependency_graph = DependencyGraph(self.loop)
def find_adjacent_memory_refs(self):
""" the pre pass already builds a hash of memory references and the
@@ -390,7 +391,7 @@
if len(self.loop.operations) <= 1 or self.early_exit_idx == -1:
return
- self.dependency_graph = dependencies =
DependencyGraph(self.loop.operations)
+ self.dependency_graph = dependencies = DependencyGraph(self.loop)
label_node = dependencies.getnode(0)
ee_guard_node = dependencies.getnode(self.early_exit_idx)
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
@@ -1122,6 +1122,8 @@
if self.metainterp.seen_loop_header_for_jdindex < 0:
if not any_operation:
+ if jitdriver_sd.vectorize:
+ self.metainterp.generate_guard(rop.GUARD_EARLY_EXIT)
return
if self.metainterp.portal_call_depth or not
self.metainterp.get_procedure_token(greenboxes, True):
if not jitdriver_sd.no_loop_header:
@@ -2133,12 +2135,6 @@
self.resumekey = compile.ResumeFromInterpDescr(original_greenkey)
self.history.inputargs = original_boxes[num_green_args:]
self.seen_loop_header_for_jdindex = -1
- # can only emit early exit if liveness is present
- # TODO think of a better way later
- if self.framestack[-1].jitcode.liveness.get(0, None) \
- and self.jitdriver_sd.vectorize:
- self.generate_guard(rop.GUARD_EARLY_EXIT)
- #self.history.record(rop.GUARD_EARLY_EXIT, [], None)
try:
self.interpret()
except SwitchToBlackhole, stb:
@@ -2318,9 +2314,7 @@
if opnum == rop.GUARD_FUTURE_CONDITION:
pass
elif opnum == rop.GUARD_EARLY_EXIT:
- # prevents it from building a bridge
- # TODO
- self.resumekey_original_loop_token = None
+ pass
elif opnum == rop.GUARD_TRUE: # a goto_if_not that jumps only now
frame.pc = frame.jitcode.follow_jump(frame.pc)
elif opnum == rop.GUARD_FALSE: # a goto_if_not that stops jumping;
diff --git a/rpython/jit/metainterp/test/test_vectorize.py
b/rpython/jit/metainterp/test/test_vectorize.py
--- a/rpython/jit/metainterp/test/test_vectorize.py
+++ b/rpython/jit/metainterp/test/test_vectorize.py
@@ -28,7 +28,7 @@
@py.test.mark.parametrize('i',[3,4,5,6,7,8,9,50])
def test_vectorize_simple_load_arith_store_int_add_index(self,i):
myjitdriver = JitDriver(greens = [],
- reds = ['i','d','bc','va','vb','vc'],
+ reds = 'auto',
vectorize=True)
def f(d):
bc = d*rffi.sizeof(rffi.SIGNED)
@@ -42,8 +42,7 @@
raw_storage_setitem(vb, j, rffi.cast(rffi.SIGNED,i))
i = 0
while i < bc:
- myjitdriver.can_enter_jit(i=i, d=d, va=va, vb=vb, vc=vc, bc=bc)
- myjitdriver.jit_merge_point(i=i, d=d, va=va, vb=vb, vc=vc,
bc=bc)
+ myjitdriver.jit_merge_point()
a = raw_storage_getitem(rffi.SIGNED,va,i)
b = raw_storage_getitem(rffi.SIGNED,vb,i)
c = a+b
@@ -62,7 +61,7 @@
if i > 3:
self.check_trace_count(1)
- @py.test.mark.parametrize('i',[1,2,3,8,17,128,500,501,502,1300])
+ @py.test.mark.parametrize('i',[1,2,3,8,17,128,130,500,501,502,1300])
def test_vectorize_array_get_set(self,i):
myjitdriver = JitDriver(greens = [],
reds = ['i','d','va','vb','vc'],
@@ -95,8 +94,40 @@
return res
res = self.meta_interp(f, [i])
assert res == f(i)
- if 4 < i:
- self.check_trace_count(1)
+ #if 4 < i:
+ # self.check_trace_count(1)
+
+ @py.test.mark.parametrize('i,k',[(9,3)])
+ def test_vector_register_too_small_vector(self, i, k):
+ myjitdriver = JitDriver(greens = [],
+ reds = 'auto',
+ vectorize=True)
+ T = lltype.Array(rffi.SHORT, hints={'nolength': True})
+ def f(d,v):
+ i = 0
+ va = lltype.malloc(T, v, flavor='raw', zero=True)
+ vb = lltype.malloc(T, v, flavor='raw', zero=True)
+ for j in range(v):
+ va[j] = rffi.r_short(1)
+ vb[j] = rffi.r_short(2)
+ while i < d:
+ myjitdriver.jit_merge_point()
+ j = 0
+ while j < v:
+ a = va[j]
+ b = vb[j]
+ ec = intmask(a) + intmask(b)
+ va[j] = rffi.r_short(ec)
+ j += 1
+
+ i += 1
+ res = intmask(va[v-1])
+ lltype.free(va, flavor='raw')
+ lltype.free(vb, flavor='raw')
+ return res
+ res = self.meta_interp(f, [i,k])
+ assert res == f(i,k)
+
class VectorizeLLtypeTests(VectorizeTests):
pass
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit