Author: Richard Plangger <r...@pasra.at> Branch: vecopt Changeset: r77956:ac80f41576c2 Date: 2015-06-08 15:03 +0200 http://bitbucket.org/pypy/pypy/changeset/ac80f41576c2/
Log: finding reduceables works, scheduling needs to be adapted next 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 @@ -1065,6 +1065,8 @@ jump(p0, i1, v3[f64|2]) """ opt = self.vectorize(self.parse_loop(trace)) + assert len(opt.packset.accum_vars) == 1 + assert opt.loop.inputargs[2] in opt.packset.accum_vars self.debug_print_operations(opt.loop) 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 @@ -292,7 +292,7 @@ if memref_a.is_adjacent_to(memref_b): pair = self.packset.can_be_packed(node_a, node_b, None) if pair: - self.packset.packs.append(pair) + self.packset.add_pack(pair) def extend_packset(self): pack_count = self.packset.pack_count() @@ -314,7 +314,7 @@ if isomorph and lnode.is_before(rnode): pair = self.packset.can_be_packed(lnode, rnode, pack) if pair: - self.packset.packs.append(pair) + self.packset.add_pack(pair) def follow_def_uses(self, pack): assert isinstance(pack, Pair) @@ -324,8 +324,9 @@ rnode = rdep.to isomorph = isomorphic(lnode.getoperation(), rnode.getoperation()) if isomorph and lnode.is_before(rnode): - if self.packset.can_be_packed(lnode, rnode, pack): - self.packset.add_pair(lnode, rnode) + pair = self.packset.can_be_packed(lnode, rnode, pack) + if pair: + self.packset.add_pack(pair) def combine_packset(self): if len(self.packset.packs) == 0: @@ -1312,23 +1313,27 @@ self.operations = operations self.unroll_count = unroll_count self.smallest_type_bytes = smallest_type_bytes + self.accum_vars = {} def pack_count(self): return len(self.packs) - def add_pair(self, l, r): - p = Pair(l,r) - self.packs.append(p) + def add_pack(self, pack): + if pack.is_accumulating(): + # remember the variable and the position in this map + self.accum_vars[pack.accum_variable] = pack.accum_variable + self.packs.append(pack) def accumulates_pair(self, lnode, rnode, origin_pack): # lnode and rnode are isomorphic and dependent + assert isinstance(origin_pack, Pair) lop = lnode.getoperation() opnum = lop.getopnum() - rop = rnode.getoperation() if opnum in (rop.FLOAT_ADD, rop.INT_ADD): + roper = rnode.getoperation() assert lop.numargs() == 2 and lop.result is not None - accum, accum_pos = self.getaccumulator_variable(lop, rop, origin_pack) + accum, accum_pos = self.getaccumulator_variable(lop, roper, origin_pack) if not accum: return None # the dependency exists only because of the result of lnode @@ -1337,6 +1342,17 @@ if not dep.because_of(accum): # not quite ... this is not handlable return None + + # in either of the two cases the arguments are mixed, + # which is not handled currently + var_pos = (accum_pos + 1) % 2 + plop = origin_pack.left.getoperation() + if lop.getarg(var_pos) is not plop.result: + return None + prop = origin_pack.right.getoperation() + if roper.getarg(var_pos) is not prop.result: + return None + # this can be handled by accumulation return AccumPair(lnode, rnode, accum, accum_pos) @@ -1344,10 +1360,11 @@ def getaccumulator_variable(self, lop, rop, origin_pack): args = rop.getarglist() - for arg, i in enumerate(args): + for i, arg in enumerate(args): + print arg, "is", lop.result if arg is lop.result: return arg, i - + # return None, -1 def can_be_packed(self, lnode, rnode, origin_pack): @@ -1357,10 +1374,12 @@ return None if origin_pack is None: return Pair(lnode, rnode) - if self.profitable_pack(lnode, rnode, origin_pack) + if self.profitable_pack(lnode, rnode, origin_pack): return Pair(lnode, rnode) else: - return self.accumulates_pair(lnode, rnode, origin_pack): + if self.contains_pair(lnode, rnode): + return None + return self.accumulates_pair(lnode, rnode, origin_pack) return None def contains_pair(self, lnode, rnode): @@ -1399,6 +1418,8 @@ for op in pack_j.operations[1:]: operations.append(op) self.packs[i] = pack = Pack(operations) + pack.accum_variable = pack_i.accum_variable + pack.accum_position = pack_i.accum_position # instead of deleting an item in the center of pack array, # the last element is assigned to position j and @@ -1411,13 +1432,6 @@ del self.packs[last_pos] return last_pos - def pack_for_operation(self, node): - for pack in self.packs: - for node2 in pack.operations: - if node == node2: - return pack - return None - class Pack(object): """ A pack is a set of n statements that are: * isomorphic @@ -1447,14 +1461,15 @@ assert isinstance(other, Pack) rightmost = self.operations[-1] leftmost = other.operations[0] - both_same_type = self.is_accumulating() == other.is_accumulating() - return rightmost == leftmost and both_same_type + return rightmost == leftmost and \ + self.accum_variable == other.accum_variable and \ + self.accum_position == other.accum_position def __repr__(self): return "Pack(%r)" % self.operations def is_accumulating(self): - return accum_position != -1 + return self.accum_variable is not None class Pair(Pack): """ A special Pack object with only two statements. """ _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit