[pypy-commit] pypy vecopt2: tested and adapted the trace optimizer for loops.
plan_rich
noreply at buildbot.pypy.org
Tue May 5 09:46:08 CEST 2015
Author: Richard Plangger <rich at pasra.at>
Branch: vecopt2
Changeset: r77115:0b90aa19f600
Date: 2015-04-16 13:01 +0200
http://bitbucket.org/pypy/pypy/changeset/0b90aa19f600/
Log: tested and adapted the trace optimizer for loops. trace jump targets
are correctly set and the vec. optimizer avoids the unroller added
vec_int_signext
diff --git a/rpython/jit/backend/llgraph/runner.py b/rpython/jit/backend/llgraph/runner.py
--- a/rpython/jit/backend/llgraph/runner.py
+++ b/rpython/jit/backend/llgraph/runner.py
@@ -563,14 +563,6 @@
else:
return self.bh_raw_load_i(struct, offset, descr)
- def bh_vec_raw_load(self, struct, offset, count, descr):
- values = []
- stride = descr.get_item_size_in_bytes()
- for i in range(count):
- val = self.bh_raw_load(struct, offset + i*stride, descr)
- values.append(val)
- return values
-
def bh_increment_debug_counter(self, addr):
p = rffi.cast(rffi.CArrayPtr(lltype.Signed), addr)
p[0] += 1
@@ -603,11 +595,6 @@
else:
self.bh_raw_store_i(struct, offset, newvalue, descr)
- def bh_vec_raw_store(self, struct, offset, newvalues, count, descr):
- stride = descr.get_item_size_in_bytes()
- for i in range(count):
- self.bh_raw_store(struct, offset + i*stride, newvalues[i], descr)
-
def bh_newstr(self, length):
return lltype.cast_opaque_ptr(llmemory.GCREF,
lltype.malloc(rstr.STR, length,
@@ -678,6 +665,39 @@
def bh_new_raw_buffer(self, size):
return lltype.malloc(rffi.CCHARP.TO, size, flavor='raw')
+ # vector operations
+ def bh_vec_int_add(self, vx, vy, count):
+ assert len(vx) == count
+ assert len(vy) == count
+ return [_vx + _vy for _vx,_vy in zip(vx,vy)]
+
+ def bh_vec_int_mul(self, vx, vy, count):
+ assert len(vx) == count
+ assert len(vy) == count
+ return [_vx * _vy for _vx,_vy in zip(vx,vy)]
+
+ def bh_vec_int_sub(self, vx, vy, count):
+ assert len(vx) == count
+ assert len(vy) == count
+ return [_vx - _vy for _vx,_vy in zip(vx,vy)]
+
+ def bh_vec_int_signext(self, vx, ext, count):
+ return [heaptracker.int_signext(_vx, ext) for _vx in vx]
+
+ def bh_vec_raw_load(self, struct, offset, count, descr):
+ values = []
+ stride = descr.get_item_size_in_bytes()
+ for i in range(count):
+ val = self.bh_raw_load(struct, offset + i*stride, descr)
+ values.append(val)
+ return values
+
+ def bh_vec_raw_store(self, struct, offset, newvalues, count, descr):
+ stride = descr.get_item_size_in_bytes()
+ for i in range(count):
+ self.bh_raw_store(struct, offset + i*stride, newvalues[i], descr)
+
+
def store_fail_descr(self, deadframe, descr):
pass # I *think*
@@ -826,6 +846,10 @@
argboxes = self.current_op.getarglist()
self.do_renaming(argboxes, args)
+ def execute_guard_no_early_exit(self, descr):
+ # TODO
+ pass
+
def execute_guard_true(self, descr, arg):
if not arg:
self.fail_guard(descr)
@@ -930,15 +954,6 @@
if not self.overflow_flag:
self.fail_guard(descr)
- def execute_vec_int_add(self, _, vx, vy):
- return [_vx + _vy for _vx,_vy in zip(vx,vy)]
-
- def execute_vec_int_mul(self, _, vx, vy):
- return [_vx * _vy for _vx,_vy in zip(vx,vy)]
-
- def execute_vec_int_sub(self, _, vx, vy):
- return [_vx - _vy for _vx,_vy in zip(vx,vy)]
-
def execute_jump(self, descr, *args):
raise Jump(descr._llgraph_target, args)
diff --git a/rpython/jit/metainterp/blackhole.py b/rpython/jit/metainterp/blackhole.py
--- a/rpython/jit/metainterp/blackhole.py
+++ b/rpython/jit/metainterp/blackhole.py
@@ -1482,6 +1482,8 @@
#
if opnum == rop.GUARD_FUTURE_CONDITION:
pass
+ elif opnum == rop.GUARD_NO_EARLY_EXIT:
+ self.position = 0
elif opnum == rop.GUARD_TRUE:
# Produced directly by some goto_if_not_xxx() opcode that did not
# jump, but which must now jump. The pc is just after the opcode.
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
@@ -685,6 +685,9 @@
class ResumeAtPositionDescr(ResumeGuardDescr):
guard_opnum = rop.GUARD_FUTURE_CONDITION
+class ResumeAtEarylExitDescr(ResumeGuardDescr):
+ guard_opnum = rop.GUARD_NO_EARLY_EXIT
+
class AllVirtuals:
llopaque = True
cache = None
@@ -773,7 +776,7 @@
elif opnum == rop.GUARD_FUTURE_CONDITION:
resumedescr = ResumeAtPositionDescr()
elif opnum == rop.GUARD_NO_EARLY_EXIT:
- resumedescr = ResumeAtPositionDescr()
+ resumedescr = ResumeAtEarylExitDescr()
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
@@ -1,4 +1,6 @@
import py
+
+from rpython.jit.metainterp.compile import ResumeAtEarylExitDescr
from rpython.jit.metainterp.optimizeopt.util import make_dispatcher_method
from rpython.jit.metainterp.resoperation import rop
from rpython.jit.codewriter.effectinfo import EffectInfo
@@ -77,14 +79,29 @@
def getindex(self):
return self.opidx
- def dependency_count(self):
- return len(self.adjacent_list)
-
def getopnum(self):
return self.op.getopnum()
def getopname(self):
return self.op.getopname()
+ def getfailarg_set(self):
+ args = set()
+ op = self.getoperation()
+ if op.getfailargs():
+ for arg in op.getfailargs():
+ args.add(arg)
+ return args
+ elif op.rd_snapshot:
+ ss = op.rd_snapshot
+ while ss != None:
+ for box in ss.boxes:
+ args.add(box)
+ ss = ss.prev
+
+ return args
+ #set(target_guard.getoperation().getfailargs())
+
+
def relax_guard_to(self, guard):
""" Relaxes a guard operation to an earlier guard. """
assert self.op.is_guard()
@@ -92,7 +109,8 @@
my_op = self.getoperation()
op = guard.getoperation()
- my_op.setdescr(op.getdescr())
+ my_op.setdescr(ResumeAtEarylExitDescr())
+ print "set ", my_op.getdescr(), "=>", op.getdescr()
my_op.setfailargs(op.getfailargs())
my_op.rd_snapshot = op.rd_snapshot
@@ -116,16 +134,6 @@
_label = getattr(dep, 'label', '')
dep.label = _label + ", " + label
- def depends_on(self, to):
- """ Does there exist a dependency from the instruction to another?
- Returns None if there is no dependency or the Dependency object in
- any other case.
- """
- for edge in self.adjacent_list:
- if edge.to == to:
- return edge
- return None
-
def clear_dependencies(self):
self.adjacent_list = []
self.adjacent_list_back = []
@@ -176,6 +184,16 @@
def depends(self):
return self.adjacent_list_back
+ def depends_on(self, to):
+ """ Does there exist a dependency from the instruction to another?
+ Returns None if there is no dependency or the Dependency object in
+ any other case.
+ """
+ for edge in self.adjacent_list:
+ if edge.to == to:
+ return edge
+ return None
+
def dependencies(self):
return self.adjacent_list[:] + self.adjacent_list_back[:] # COPY
@@ -444,10 +462,9 @@
# pass 3 find schedulable nodes
jump_node = self.nodes[jump_pos]
label_node = self.nodes[label_pos]
- self.schedulable_nodes.append(label_node)
for node in self.nodes:
if node != jump_node:
- if node.dependency_count() == 0:
+ if node.depends_count() == 0:
self.schedulable_nodes.append(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
@@ -633,15 +650,16 @@
def schedule(self, index):
node = self.schedulable_nodes[index]
- assert not node.emitted
+ assert not node.emitted, "node " + str(node) + " cannot be emitted twice! op: " + str(node.getoperation())
del self.schedulable_nodes[index]
to_del = []
print " schedule", node.getoperation()
for dep in node.provides()[:]: # COPY
- node.remove_edge_to(dep.to)
- print " >=X=>", node, dep.to, "count",dep.to.depends_count()
- if dep.to.depends_count() == 0:
- self.schedulable_nodes.append(dep.to)
+ to = dep.to
+ node.remove_edge_to(to)
+ print " >=X=>", node, to, "count",to.depends_count()
+ if not to.emitted and to.depends_count() == 0:
+ self.schedulable_nodes.append(to)
node.clear_dependencies()
node.emitted = True
diff --git a/rpython/jit/metainterp/optimizeopt/optimizer.py b/rpython/jit/metainterp/optimizeopt/optimizer.py
--- a/rpython/jit/metainterp/optimizeopt/optimizer.py
+++ b/rpython/jit/metainterp/optimizeopt/optimizer.py
@@ -796,7 +796,9 @@
assert pendingfields is not None
if op.getdescr() is not None:
descr = op.getdescr()
- assert isinstance(descr, compile.ResumeAtPositionDescr)
+ assert isinstance(descr, compile.ResumeAtPositionDescr) or \
+ isinstance(descr, compile.ResumeAtEarylExitDescr)
+
else:
descr = compile.invent_fail_descr_for_op(op.getopnum(), self)
op.setdescr(descr)
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,8 @@
import sys
import py
from rpython.rtyper.lltypesystem import lltype, rffi
-from rpython.jit.metainterp.history import ConstInt, VECTOR, BoxVector
+from rpython.jit.metainterp.history import (ConstInt, VECTOR, BoxVector,
+ TargetToken, JitCellToken)
from rpython.jit.metainterp.optimizeopt.optimizer import Optimizer, Optimization
from rpython.jit.metainterp.optimizeopt.util import make_dispatcher_method
from rpython.jit.metainterp.optimizeopt.dependency import (DependencyGraph,
@@ -57,17 +58,24 @@
self.memory_refs = []
self.dependency_graph = None
self.first_debug_merge_point = False
- self.last_debug_merge_point = None
self.packset = None
self.unroll_count = 0
self.smallest_type_bytes = 0
def propagate_all_forward(self):
self.clear_newoperations()
+ label = self.loop.operations[0]
+ jump = self.loop.operations[-1]
+ if jump.getopnum() != rop.LABEL:
+ # compile_loop appends a additional label to all loops
+ # we cannot optimize normal traces
+ raise NotAVectorizeableLoop()
+
self.linear_find_smallest_type(self.loop)
byte_count = self.smallest_type_bytes
- if byte_count == 0:
+ if byte_count == 0 or label.getopnum() != rop.LABEL:
# stop, there is no chance to vectorize this trace
+ # we cannot optimize normal traces (if there is no label)
raise NotAVectorizeableLoop()
# unroll
@@ -88,15 +96,8 @@
self._newoperations.append(op)
def emit_unrolled_operation(self, op):
- if op.getopnum() == rop.DEBUG_MERGE_POINT:
- self.last_debug_merge_point = op
- if not self.first_debug_merge_point:
- self.first_debug_merge_point = True
- else:
- return False
self._last_emitted_op = op
self._newoperations.append(op)
- return True
def unroll_loop_iterations(self, loop, unroll_count):
""" Unroll the loop X times. unroll_count is an integral how
@@ -104,10 +105,12 @@
"""
op_count = len(loop.operations)
- label_op = loop.operations[0]
- jump_op = loop.operations[op_count-1]
+ label_op = loop.operations[0].clone()
+ jump_op = loop.operations[op_count-1].clone()
+ # use the target token of the label
+ jump_op = ResOperation(rop.JUMP, jump_op.getarglist(), None, label_op.getdescr())
assert label_op.getopnum() == rop.LABEL
- assert jump_op.is_final() or jump_op.getopnum() == rop.LABEL
+ assert jump_op.is_final()
# XXX self.vec_info.track_memory_refs = True
@@ -124,8 +127,6 @@
op = loop.operations[i].clone()
operations.append(op)
self.emit_unrolled_operation(op)
- #self.vec_info.index = len(self._newoperations)-1
- #self.vec_info.inspect_operation(op)
orig_jump_args = jump_op.getarglist()[:]
# it is assumed that #label_args == #jump_args
@@ -167,14 +168,15 @@
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)
+ if copied_op.getfailargs():
+ 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)
@@ -189,9 +191,6 @@
except KeyError:
pass
- if self.last_debug_merge_point is not None:
- self._last_emitted_op = self.last_debug_merge_point
- self._newoperations.append(self.last_debug_merge_point)
self.emit_unrolled_operation(jump_op)
def clone_snapshot(self, snapshot, rename_map):
@@ -335,10 +334,10 @@
print " P:", pack
def schedule(self):
+ print self.dependency_graph.as_dot()
self.clear_newoperations()
scheduler = Scheduler(self.dependency_graph, VecScheduleData())
- print "scheduling loop"
- i = 100
+ print "scheduling loop. scheduleable are: " + str(scheduler.schedulable_nodes)
while scheduler.has_more():
candidate = scheduler.next()
print " candidate", candidate, "has pack?", candidate.pack != None, "pack", candidate.pack
@@ -353,9 +352,6 @@
else:
self.emit_operation(candidate.getoperation())
scheduler.schedule(0)
- i += 1
- if i > 200:
- assert False
self.loop.operations = self._newoperations[:]
if not we_are_translated():
@@ -415,8 +411,8 @@
return False
def fail_args_break_dependency(guard, prev_op, target_guard):
- failargs = set(guard.getoperation().getfailargs())
- new_failargs = set(target_guard.getoperation().getfailargs())
+ failargs = guard.getfailarg_set()
+ new_failargs = target_guard.getfailarg_set()
op = prev_op.getoperation()
if not op.is_always_pure(): # TODO has_no_side_effect():
@@ -439,53 +435,52 @@
self.box_to_vbox = {}
def as_vector_operation(self, pack):
- assert len(pack.operations) > 1
+ op_count = pack.operations
+ assert op_count > 1
self.pack = pack
+ # properties that hold for the pack are:
+ # isomorphism (see func above)
op0 = pack.operations[0].getoperation()
assert op0.vector != -1
args = op0.getarglist()[:]
- if op0.vector in (rop.VEC_RAW_LOAD, rop.VEC_RAW_STORE):
- args.append(ConstInt(0))
- vop = ResOperation(op0.vector, args,
- op0.result, op0.getdescr())
- self._inspect_operation(vop) # op0 is for dispatch only
- #if op0.vector not in (rop.VEC_RAW_LOAD, rop.VEC_RAW_STORE):
- # op_count = len(pack.operations)
- # args.append(ConstInt(op_count))
+ args.append(ConstInt(len(op_count)))
+ vop = ResOperation(op0.vector, args, op0.result, op0.getdescr())
+ self._inspect_operation(vop)
return vop
- def _pack_vector_arg(self, vop, op, i, vbox):
- arg = op.getarg(i)
- if vbox is None:
- try:
- _, vbox = self.box_to_vbox[arg]
- except KeyError:
- vbox = BoxVector(arg.type, 4, 0, True)
- vop.setarg(i, vbox)
- self.box_to_vbox[arg] = (i,vbox)
- return vbox
+ def get_vbox_for(self, arg):
+ try:
+ _, vbox = self.box_to_vbox[arg]
+ return vbox
+ except KeyError:
+ # if this is not the case, then load operations must
+ # be emitted
+ assert False, "vector box MUST be defined before"
- def _pack_vector_result(self, vop, op, vbox):
- result = op.result
- if vbox is None:
- vbox = BoxVector(result.type, 4, 0, True)
- vop.result = vbox
- self.box_to_vbox[result] = (-1,vbox)
- return vbox
+ def vector_result(self, vop):
+ ops = self.pack.operations
+ op0 = ops[0].getoperation()
+ result = op0.result
+ vbox = BoxVector(result.type, 4, 0, True)
+ vop.result = vbox
+ i = 0
+ vboxcount = vbox.item_count = len(ops)
+ while i < vboxcount:
+ op = ops[i].getoperation()
+ self.box_to_vbox[result] = (i, vbox)
+ i += 1
+
+ def vector_arg(self, vop, argidx):
+ ops = self.pack.operations
+ op0 = ops[0].getoperation()
+ vbox = self.get_vbox_for(op0.getarg(argidx))
+ vop.setarg(argidx, vbox)
bin_arith_trans = """
def _vectorize_{name}(self, vop):
- vbox_arg_0 = None
- vbox_arg_1 = None
- vbox_result = None
- ops = self.pack.operations
- for i, node in enumerate(ops):
- op = node.getoperation()
- vbox_arg_0 = self._pack_vector_arg(vop, op, 0, vbox_arg_0)
- vbox_arg_1 = self._pack_vector_arg(vop, op, 1, vbox_arg_1)
- vbox_result= self._pack_vector_result(vop, op, vbox_result)
- vbox_arg_0.item_count = vbox_arg_1.item_count = \
- vbox_result.item_count = len(ops)
+ self.vector_arg(vop, 0)
+ self.vector_arg(vop, 1)
+ self.vector_result(vop)
"""
exec py.code.Source(bin_arith_trans.format(name='VEC_INT_ADD')).compile()
exec py.code.Source(bin_arith_trans.format(name='VEC_INT_MUL')).compile()
@@ -495,23 +490,16 @@
exec py.code.Source(bin_arith_trans.format(name='VEC_FLOAT_SUB')).compile()
del bin_arith_trans
+ def _vectorize_VEC_INT_SIGNEXT(self, vop):
+ self.vector_arg(vop, 0)
+ # arg 1 is a constant
+ self.vector_result(vop)
+
def _vectorize_VEC_RAW_LOAD(self, vop):
- vbox_result = None
- ops = self.pack.operations
- for i, node in enumerate(ops):
- op = node.getoperation()
- vbox_result= self._pack_vector_result(vop, op, vbox_result)
- vbox_result.item_count = len(ops)
- vop.setarg(vop.numargs()-1,ConstInt(len(ops)))
+ self.vector_result(vop)
def _vectorize_VEC_RAW_STORE(self, vop):
- vbox_arg_2 = None
- ops = self.pack.operations
- for i, node in enumerate(ops):
- op = node.getoperation()
- vbox_arg_2 = self._pack_vector_arg(vop, op, 2, vbox_arg_2)
- vbox_arg_2.item_count = len(ops)
- vop.setarg(vop.numargs()-1,ConstInt(len(ops)))
+ self.vector_arg(vop, 2)
VecScheduleData._inspect_operation = \
make_dispatcher_method(VecScheduleData, '_vectorize_')
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
@@ -452,12 +452,13 @@
#
# vector operations
'_VEC_ARITHMETIC_FIRST',
- 'VEC_INT_ADD/2d',
- 'VEC_INT_SUB/2d',
- 'VEC_INT_MUL/2d',
- 'VEC_FLOAT_ADD/2d',
- 'VEC_FLOAT_SUB/2d',
- 'VEC_FLOAT_MUL/2d',
+ 'VEC_INT_ADD/3',
+ 'VEC_INT_SUB/3',
+ 'VEC_INT_MUL/3',
+ 'VEC_FLOAT_ADD/3',
+ 'VEC_FLOAT_SUB/3',
+ 'VEC_FLOAT_MUL/3',
+ 'VEC_INT_SIGNEXT/3',
'_VEC_ARITHMETIC_LAST',
#
'INT_LT/2b',
@@ -703,20 +704,22 @@
rop.PTR_NE: rop.PTR_NE,
}
_opvector = {
- rop.RAW_LOAD: rop.VEC_RAW_LOAD,
+ rop.RAW_LOAD: rop.VEC_RAW_LOAD,
rop.GETARRAYITEM_RAW: rop.VEC_RAW_LOAD,
- rop.GETARRAYITEM_GC: rop.VEC_RAW_LOAD,
+ rop.GETARRAYITEM_GC: rop.VEC_RAW_LOAD,
- rop.RAW_STORE: rop.VEC_RAW_STORE,
+ rop.RAW_STORE: rop.VEC_RAW_STORE,
rop.SETARRAYITEM_RAW: rop.VEC_RAW_STORE,
- rop.SETARRAYITEM_GC: rop.VEC_RAW_STORE,
+ rop.SETARRAYITEM_GC: rop.VEC_RAW_STORE,
- rop.INT_ADD: rop.VEC_INT_ADD,
- rop.INT_SUB: rop.VEC_INT_SUB,
- rop.INT_MUL: rop.VEC_INT_MUL,
+ rop.INT_ADD: rop.VEC_INT_ADD,
+ rop.INT_SUB: rop.VEC_INT_SUB,
+ rop.INT_MUL: rop.VEC_INT_MUL,
rop.FLOAT_ADD: rop.VEC_FLOAT_ADD,
rop.FLOAT_SUB: rop.VEC_FLOAT_SUB,
rop.FLOAT_MUL: rop.VEC_FLOAT_MUL,
+
+ rop.INT_SIGNEXT: rop.VEC_INT_SIGNEXT,
}
def setup2():
@@ -730,7 +733,6 @@
cls.boolinverse = _opboolinverse[opnum]
if opnum in _opvector:
cls.vector = _opvector[opnum]
-
setup2()
del _opboolinverse
del _opboolreflex
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
@@ -21,63 +21,24 @@
CPUClass=self.CPUClass,
type_system=self.type_system)
- def test_vectorize_simple_load_arith_store_mul(self):
- myjitdriver = JitDriver(greens = [],
- reds = ['i','d','va','vb','vc'],
- vectorize=False)
- def f(d):
- va = alloc_raw_storage(d*rffi.sizeof(rffi.SIGNED), zero=True)
- vb = alloc_raw_storage(d*rffi.sizeof(rffi.SIGNED), zero=True)
- vc = alloc_raw_storage(d*rffi.sizeof(rffi.SIGNED), zero=True)
- for i in range(d):
- raw_storage_setitem(va, i*rffi.sizeof(rffi.SIGNED),
- rffi.cast(rffi.SIGNED,i))
- raw_storage_setitem(vb, i*rffi.sizeof(rffi.SIGNED),
- rffi.cast(rffi.SIGNED,i))
- i = 0
- 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)
- pos = i*rffi.sizeof(rffi.SIGNED)
- a = raw_storage_getitem(rffi.SIGNED,va,pos)
- b = raw_storage_getitem(rffi.SIGNED,vb,pos)
- c = a+b
- raw_storage_setitem(vc, pos, rffi.cast(rffi.SIGNED,c))
- i += 1
- res = 0
- for i in range(d):
- res += raw_storage_getitem(rffi.SIGNED,vc,i*rffi.sizeof(rffi.SIGNED))
-
- free_raw_storage(va)
- free_raw_storage(vb)
- free_raw_storage(vc)
- return res
- i = 32
- res = self.meta_interp(f, [i])
- assert res == f(i)
- self.check_trace_count(1)
- i = 31
- res = self.meta_interp(f, [i])
- assert res == f(i)
-
- @py.test.mark.parametrize('i',range(0,32))
+ @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','va','vb','vc'],
+ reds = ['i','d','bc','va','vb','vc'],
vectorize=True)
def f(d):
- va = alloc_raw_storage(d*rffi.sizeof(rffi.SIGNED), zero=True)
- vb = alloc_raw_storage(d*rffi.sizeof(rffi.SIGNED), zero=True)
- vc = alloc_raw_storage(d*rffi.sizeof(rffi.SIGNED), zero=True)
+ bc = d*rffi.sizeof(rffi.SIGNED)
+ va = alloc_raw_storage(bc, zero=True)
+ vb = alloc_raw_storage(bc, zero=True)
+ vc = alloc_raw_storage(bc, zero=True)
for i in range(d):
- raw_storage_setitem(va, i*rffi.sizeof(rffi.SIGNED),
- rffi.cast(rffi.SIGNED,i))
- raw_storage_setitem(vb, i*rffi.sizeof(rffi.SIGNED),
- rffi.cast(rffi.SIGNED,i))
+ j = i*rffi.sizeof(rffi.SIGNED)
+ raw_storage_setitem(va, j, rffi.cast(rffi.SIGNED,i))
+ raw_storage_setitem(vb, j, rffi.cast(rffi.SIGNED,i))
i = 0
- while i < d*8:
- 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)
+ 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)
a = raw_storage_getitem(rffi.SIGNED,va,i)
b = raw_storage_getitem(rffi.SIGNED,vb,i)
c = a+b
@@ -92,8 +53,9 @@
free_raw_storage(vc)
return res
res = self.meta_interp(f, [i])
- assert res == f(i) #sum(range(i)) * 2
- self.check_trace_count(1)
+ assert res == f(i)
+ if i > 3:
+ self.check_trace_count(1)
def test_guard(self):
py.test.skip('abc')
More information about the pypy-commit
mailing list