Author: Richard Plangger <[email protected]>
Branch: vecopt
Changeset: r78454:bdcb22955f5c
Date: 2015-07-06 13:20 +0200
http://bitbucket.org/pypy/pypy/changeset/bdcb22955f5c/
Log: advanced the bridge building from an early exit, nearly working but
there are some problems to solve which accumulation and the input
arguments...
diff --git a/pypy/module/micronumpy/test/test_zjit.py
b/pypy/module/micronumpy/test/test_zjit.py
--- a/pypy/module/micronumpy/test/test_zjit.py
+++ b/pypy/module/micronumpy/test/test_zjit.py
@@ -130,7 +130,7 @@
def test_dot_matrix(self):
result = self.run("dot_matrix")
assert int(result) == 86
- self.check_vectorized(1, 1)
+ self.check_vectorized(2, 1)
def define_float32_copy():
return """
@@ -529,13 +529,13 @@
result = self.run("prod")
assert int(result) == 576
self.check_trace_count(1)
- self.check_vectorized(1, 1)
+ self.check_vectorized(2, 1)
def test_prod_zero(self):
result = self.run("prod_zero")
assert int(result) == 0
self.check_trace_count(1)
- self.check_vectorized(1, 1)
+ self.check_vectorized(2, 1)
def define_max():
@@ -768,7 +768,7 @@
result = self.run("setslice")
assert result == 5.5
self.check_trace_count(1)
- self.check_vectorized(1, 1)
+ self.check_vectorized(2, 1)
def define_virtual_slice():
return """
@@ -834,7 +834,7 @@
def test_dot(self):
result = self.run("dot")
assert result == 184
- self.check_trace_count(5)
+ self.check_trace_count(4)
self.check_vectorized(3,1)
def define_argsort():
@@ -848,7 +848,7 @@
result = self.run("argsort")
assert result == 6
self.check_trace_count(1)
- self.check_vectorized(1,1) # vec. setslice
+ self.check_vectorized(2,1) # vec. setslice
def define_where():
return """
@@ -909,7 +909,7 @@
result = self.run("slice")
assert result == 18
self.check_trace_count(1)
- self.check_vectorized(1,1)
+ self.check_vectorized(2,1)
def define_multidim_slice():
return """
diff --git a/rpython/jit/backend/x86/vector_ext.py
b/rpython/jit/backend/x86/vector_ext.py
--- a/rpython/jit/backend/x86/vector_ext.py
+++ b/rpython/jit/backend/x86/vector_ext.py
@@ -9,11 +9,17 @@
ebp, r8, r9, r10, r11, r12, r13, r14, r15, xmm0, xmm1, xmm2, xmm3, xmm4,
xmm5, xmm6, xmm7, xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14,
X86_64_SCRATCH_REG, X86_64_XMM_SCRATCH_REG, AddressLoc)
+from rpython.jit.backend.llsupport.regalloc import (get_scale,
valid_addressing_size)
+# duplicated for easy migration, def in assembler.py as well
+# DUP START
def addr_add(reg_or_imm1, reg_or_imm2, offset=0, scale=0):
- # duplicated for easy migration, def in assembler.py as well
return AddressLoc(reg_or_imm1, reg_or_imm2, scale, offset)
+def heap(addr):
+ return AddressLoc(ImmedLoc(addr), imm0, 0, 0)
+# DUP END
+
class VectorAssemblerMixin(object):
_mixin_ = True
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
@@ -189,19 +189,25 @@
send_loop_to_backend(greenkey, jitdriver_sd, metainterp_sd, loop, "loop")
record_loop_or_bridge(metainterp_sd, loop)
- generate_pending_loop_versions(loop, jitdriver_sd, metainterp_sd,
jitcell_token)
+ generate_pending_loop_versions(loop, jitdriver_sd, metainterp,
jitcell_token)
return all_target_tokens[0]
-def generate_pending_loop_versions(loop, jitdriver_sd, metainterp_sd,
jitcell_token):
+def generate_pending_loop_versions(loop, jitdriver_sd, metainterp,
jitcell_token):
+ metainterp_sd = metainterp.staticdata
if loop.versions is not None:
token = jitcell_token
for version in loop.versions:
- version.update_inputargs()
- for faildescr in version.faildescrs:
+ versioned_loop = create_empty_loop(metainterp)
+ versioned_loop.inputargs = version.inputargs
+ versioned_loop.operations = version.operations
+ versioned_loop.original_jitcell_token = jitcell_token
+ for _, faildescr in version.faildescrs:
send_bridge_to_backend(jitdriver_sd, metainterp_sd,
faildescr, version.inputargs,
version.operations, jitcell_token)
+ versioned_loop.original_jitcell_token = jitcell_token
+ record_loop_or_bridge(metainterp_sd, versioned_loop)
def compile_retrace(metainterp, greenkey, start,
inputargs, jumpargs,
@@ -395,8 +401,7 @@
operations, original_loop_token):
if not we_are_translated():
show_procedures(metainterp_sd)
- seen = dict.fromkeys(inputargs)
- TreeLoop.check_consistency_of_branch(operations, seen)
+ TreeLoop.check_consistency_of_branch(operations,
TreeLoop.seen_args(inputargs))
if metainterp_sd.warmrunnerdesc is not None:
hooks = metainterp_sd.warmrunnerdesc.hooks
debug_info = JitDebugInfo(jitdriver_sd, metainterp_sd.logger_ops,
diff --git a/rpython/jit/metainterp/history.py
b/rpython/jit/metainterp/history.py
--- a/rpython/jit/metainterp/history.py
+++ b/rpython/jit/metainterp/history.py
@@ -702,17 +702,24 @@
self.aligned = aligned
self.faildescrs = []
#
- label = self.operations[0]
+ i = 0
+ label = self.operations[i]
+ while i < len(self.operations):
+ label = self.operations[i]
+ if label.getopnum() == rop.LABEL:
+ break
+ i += 1
assert label.getopnum() == rop.LABEL
- self.enter_args = label.getarglist()
- self.calling_args = None
+ self.label_pos = i
+ self.parent_trace_label_args = None
+ self.bridge_label_args = label.getarglist()
self.inputargs = None
- def adddescr(self, descr):
- self.faildescrs.append(descr)
+ def adddescr(self, op, descr):
+ self.faildescrs.append((op, descr))
def update_token(self, jitcell_token):
- label = self.operations[0]
+ label = self.operations[self.label_pos]
jump = self.operations[-1]
#
assert label.getopnum() == rop.LABEL
@@ -722,15 +729,16 @@
token.original_jitcell_token = jitcell_token
label.setdescr(token)
jump.setdescr(token)
+
+ assert len(self.bridge_label_args) <= len(self.parent_trace_label_args)
+ for i in range(len(self.bridge_label_args)):
+ arg = self.parent_trace_label_args[i]
+ if isinstance(arg, BoxVectorAccum):
+ self.bridge_label_args[i] = arg
+ self.inputargs = self.bridge_label_args
+
return token
- def update_inputargs(self):
- assert len(self.enter_args) == len(self.inputargs)
- rename = { a: b for a,b in zip(self.enter_args, self.calling_args) }
- for i, arg in enumerate(self.inputargs):
- self.inputargs[i] = rename[arg]
-
-
class TreeLoop(object):
inputargs = None
operations = None
@@ -791,12 +799,23 @@
def check_consistency_of(inputargs, operations):
for box in inputargs:
assert isinstance(box, Box), "Loop.inputargs contains %r" % (box,)
- seen = dict.fromkeys(inputargs)
+ seen = TreeLoop.seen_args(inputargs)
assert len(seen) == len(inputargs), (
"duplicate Box in the Loop.inputargs")
TreeLoop.check_consistency_of_branch(operations, seen)
@staticmethod
+ def seen_args(inputargs):
+ seen = {}
+ for arg in inputargs:
+ if isinstance(arg, BoxVectorAccum):
+ seen[arg.scalar_var] = None
+ seen[arg] = None
+ else:
+ seen[arg] = None
+ return seen
+
+ @staticmethod
def check_consistency_of_branch(operations, seen):
"NOT_RPYTHON"
for op in operations:
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
@@ -137,7 +137,9 @@
def exits_early(self):
if self.op.is_guard():
- return isinstance(self.op.getdescr(),
compile.ResumeAtLoopHeaderDescr)
+ descr = self.op.getdescr()
+ return isinstance(descr, compile.ResumeAtLoopHeaderDescr) or \
+ isinstance(descr, compile.CompileLoopVersionDescr)
return False
def is_guard_early_exit(self):
@@ -292,7 +294,10 @@
return None
def __repr__(self):
- return "Node(opidx: %d)" % self.opidx
+ pack = ''
+ if self.pack:
+ pack = "p: %d" % self.pack.opcount()
+ return "Node(%s,%s i: %d)" % (self.op.getopname(), pack, self.opidx)
def __ne__(self, other):
return not self.__eq__(other)
@@ -625,7 +630,8 @@
self.guard_argument_protection(guard_node, tracker)
#
descr = guard_op.getdescr()
- if isinstance(descr, compile.ResumeAtLoopHeaderDescr):
+ if isinstance(descr, compile.ResumeAtLoopHeaderDescr) or \
+ isinstance(descr, compile.CompileLoopVersionDescr):
return
# handle fail args
if guard_op.getfailargs():
diff --git a/rpython/jit/metainterp/optimizeopt/unroll.py
b/rpython/jit/metainterp/optimizeopt/unroll.py
--- a/rpython/jit/metainterp/optimizeopt/unroll.py
+++ b/rpython/jit/metainterp/optimizeopt/unroll.py
@@ -36,6 +36,8 @@
imp.import_value(value)
def emit_operation(self, op):
+ if op.getopnum() == rop.GUARD_EARLY_EXIT:
+ return
if op.returns_bool_result():
self.bool_boxes[self.getvalue(op.result)] = None
if self.emitting_dissabled:
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
@@ -168,6 +168,8 @@
def emit_operation(self, op):
if op.getopnum() == rop.DEBUG_MERGE_POINT:
return
+ if op.getopnum() == rop.GUARD_EARLY_EXIT:
+ return
self._last_emitted_op = op
self._newoperations.append(op)
@@ -196,7 +198,7 @@
self.emit_unrolled_operation(label_op)
- self.orig_loop_version.calling_args = label_op.getarglist()
+ self.orig_loop_version.parent_trace_label_args =
label_op.getarglist()[:]
renamer = Renamer()
oi = 0
@@ -583,9 +585,9 @@
label_node.edge_to(last_but_one, label='pullup')
# 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)
+ self.relax_guard_to(guard_node, ee_guard_node, label_node)
- def relax_guard_to(self, guard_node, other_node):
+ def relax_guard_to(self, guard_node, other_node, label_node):
""" Relaxes a guard operation to an earlier guard. """
# clone this operation object. if the vectorizer is
# not able to relax guards, it won't leave behind a modified operation
@@ -599,12 +601,14 @@
descr = CompileLoopVersionDescr()
if olddescr:
descr.copy_all_attributes_from(olddescr)
- self.orig_loop_version.inputargs = op.getfailargs()
- self.orig_loop_version.adddescr(descr)
#
tgt_op.setdescr(descr)
tgt_op.rd_snapshot = op.rd_snapshot
tgt_op.setfailargs(op.getfailargs())
+ if tgt_op.getopnum() in (rop.GUARD_TRUE, rop.GUARD_FALSE):
+ self.orig_loop_version.adddescr(tgt_op, descr)
+ tgt_op.setfailargs(label_node.getoperation().getarglist()[:])
+ tgt_op.rd_snapshot = None
class CostModel(object):
@@ -849,6 +853,7 @@
for pack in self.packs:
if not pack.is_accumulating():
continue
+ import pdb; pdb.set_trace()
accum = pack.accum
# create a new vector box for the parameters
box = pack.input_type.new_vector_box()
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
@@ -63,7 +63,7 @@
@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'],
+ reds = 'auto',
vectorize=True)
T = lltype.Array(rffi.INT, hints={'nolength': True})
def f(d):
@@ -75,8 +75,7 @@
va[j] = rffi.r_int(j)
vb[j] = rffi.r_int(j)
while i < d:
- myjitdriver.can_enter_jit(i=i, d=d, va=va, vb=vb, vc=vc)
- myjitdriver.jit_merge_point(i=i, d=d, va=va, vb=vb, vc=vc)
+ myjitdriver.jit_merge_point()
a = va[i]
b = vb[i]
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit