コード例 #1
0
ファイル: vector.py プロジェクト: sota/pypy-old
def isomorphic(l_op, r_op):
    """ Subject of definition, here it is equal operation.
        See limintations (vectorization.rst).
    """
    if l_op.getopnum() == r_op.getopnum():
        l_vecinfo = forwarded_vecinfo(l_op)
        r_vecinfo = forwarded_vecinfo(r_op)
        return l_vecinfo.bytesize == r_vecinfo.bytesize
    return False
コード例 #2
0
ファイル: vector.py プロジェクト: Mu-L/pypy
    def accumulates_pair(self, lnode, rnode, origin_pack):
        # lnode and rnode are isomorphic and dependent
        assert isinstance(origin_pack, Pair)
        left = lnode.getoperation()
        opnum = left.getopnum()

        try:
            operator = AccumPack.SUPPORTED(opnum)
        except KeyError:
            pass
        else:
            right = rnode.getoperation()
            assert left.numargs() == 2 and not left.returns_void()
            scalar, index = self.getaccumulator_variable(
                left, right, origin_pack)
            if not scalar:
                return None
            # the dependency exists only because of the left?
            for dep in lnode.provides():
                if dep.to is rnode:
                    if not dep.because_of(scalar):
                        # not quite ... this is not handlable
                        return None
            # get the original variable
            scalar = left.getarg(index)

            # in either of the two cases the arguments are mixed,
            # which is not handled currently
            other_index = (index + 1) % 2
            if left.getarg(other_index) is not origin_pack.leftmost():
                return None
            if right.getarg(other_index) is not origin_pack.rightmost():
                return None

            # this can be handled by accumulation
            size = INT_WORD
            if left.type == 'f':
                size = FLOAT_WORD
            l_vecinfo = forwarded_vecinfo(left)
            r_vecinfo = forwarded_vecinfo(right)
            if not (l_vecinfo.bytesize == r_vecinfo.bytesize
                    and l_vecinfo.bytesize == size):
                # do not support if if the type size is smaller
                # than the cpu word size.
                # WHY?
                # to ensure accum is done on the right size, the dependencies
                # of leading/preceding signext/floatcast instructions needs to be
                # considered. => tree pattern matching problem.
                return None
            return AccumPack([lnode, rnode], operator, index)
        is_guard = left.is_guard() and left.getopnum() in (rop.GUARD_TRUE,
                                                           rop.GUARD_FALSE)
        if is_guard:
            return AccumPack([lnode, rnode], 'g', 0)

        return None
コード例 #3
0
ファイル: vector.py プロジェクト: abhinavthomas/pypy
    def accumulates_pair(self, lnode, rnode, origin_pack):
        # lnode and rnode are isomorphic and dependent
        assert isinstance(origin_pack, Pair)
        left = lnode.getoperation()
        opnum = left.getopnum()

        if opnum in AccumPack.SUPPORTED:
            right = rnode.getoperation()
            assert left.numargs() == 2 and not left.returns_void()
            scalar, index = self.getaccumulator_variable(left, right, origin_pack)
            if not scalar:
                return None
            # the dependency exists only because of the left?
            for dep in lnode.provides():
                if dep.to is rnode:
                    if not dep.because_of(scalar):
                        # not quite ... this is not handlable
                        return None
            # get the original variable
            scalar = left.getarg(index)

            # in either of the two cases the arguments are mixed,
            # which is not handled currently
            other_index = (index + 1) % 2
            if left.getarg(other_index) is not origin_pack.leftmost():
                return None
            if right.getarg(other_index) is not origin_pack.rightmost():
                return None

            # this can be handled by accumulation
            size = INT_WORD
            if left.type == 'f':
                size = FLOAT_WORD
            l_vecinfo = forwarded_vecinfo(left)
            r_vecinfo = forwarded_vecinfo(right)
            if not (l_vecinfo.bytesize == r_vecinfo.bytesize and l_vecinfo.bytesize == size):
                # do not support if if the type size is smaller
                # than the cpu word size.
                # WHY?
                # to ensure accum is done on the right size, the dependencies
                # of leading/preceding signext/floatcast instructions needs to be
                # considered. => tree pattern matching problem.
                return None
            operator = AccumPack.SUPPORTED[opnum]
            return AccumPack([lnode, rnode], operator, index)
        is_guard = left.is_guard() and left.getopnum() in (rop.GUARD_TRUE, rop.GUARD_FALSE)
        if is_guard:
            return AccumPack([lnode, rnode], 'g', 0)

        return None
コード例 #4
0
ファイル: vector_ext.py プロジェクト: mozillazg/pypy
 def check(self, value):
     vecinfo = forwarded_vecinfo(value)
     assert vecinfo.datatype != '\x00'
     if self.type != TypeRestrict.ANY_TYPE:
         if self.type != vecinfo.datatype:
             msg = "type mismatch %s != %s" % \
                     (self.type, vecinfo.datatype)
             failnbail_transformation(msg)
     assert vecinfo.bytesize > 0
     if not self.any_size():
         if self.bytesize != vecinfo.bytesize:
             msg = "bytesize mismatch %s != %s" % \
                     (self.bytesize, vecinfo.bytesize)
             failnbail_transformation(msg)
     assert vecinfo.count > 0
     if self.count != TypeRestrict.ANY_COUNT:
         if vecinfo.count < self.count:
             msg = "count mismatch %s < %s" % \
                     (self.count, vecinfo.count)
             failnbail_transformation(msg)
     if self.sign != TypeRestrict.ANY_SIGN:
         if bool(self.sign) == vecinfo.sign:
             msg = "sign mismatch %s < %s" % \
                     (self.sign, vecinfo.sign)
             failnbail_transformation(msg)
コード例 #5
0
 def check(self, value):
     vecinfo = forwarded_vecinfo(value)
     assert vecinfo.datatype != '\x00'
     if self.type != TypeRestrict.ANY_TYPE:
         if self.type != vecinfo.datatype:
             msg = "type mismatch %s != %s" % \
                     (self.type, vecinfo.datatype)
             failnbail_transformation(msg)
     assert vecinfo.bytesize > 0
     if not self.any_size():
         if self.bytesize != vecinfo.bytesize:
             msg = "bytesize mismatch %s != %s" % \
                     (self.bytesize, vecinfo.bytesize)
             failnbail_transformation(msg)
     assert vecinfo.count > 0
     if self.count != TypeRestrict.ANY_COUNT:
         if vecinfo.count < self.count:
             msg = "count mismatch %s < %s" % \
                     (self.count, vecinfo.count)
             failnbail_transformation(msg)
     if self.sign != TypeRestrict.ANY_SIGN:
         if bool(self.sign) == vecinfo.sign:
             msg = "sign mismatch %s < %s" % \
                     (self.sign, vecinfo.sign)
             failnbail_transformation(msg)
コード例 #6
0
ファイル: vector.py プロジェクト: sota/pypy-old
 def record_vector_pack(self, src, index, count):
     vecinfo = forwarded_vecinfo(src)
     if vecinfo.datatype == FLOAT:
         if index == 1 and count == 1:
             self.savings -= 2
             return
     self.savings -= count
コード例 #7
0
ファイル: vector_ext.py プロジェクト: mozillazg/pypy
 def opcount_filling_vector_register(self, op, vec_reg_size):
     """ How many operations of that kind can one execute
         with a machine instruction of register size X?
     """
     if op.is_typecast():
         if op.casts_down():
             size = op.cast_input_bytesize(vec_reg_size)
             return size // op.cast_from_bytesize()
         else:
             return vec_reg_size // op.cast_to_bytesize()
     vecinfo = forwarded_vecinfo(op)
     return  vec_reg_size // vecinfo.bytesize
コード例 #8
0
 def opcount_filling_vector_register(self, op, vec_reg_size):
     """ How many operations of that kind can one execute
         with a machine instruction of register size X?
     """
     if op.is_typecast():
         if op.casts_down():
             size = op.cast_input_bytesize(vec_reg_size)
             return size // op.cast_from_bytesize()
         else:
             return vec_reg_size // op.cast_to_bytesize()
     vecinfo = forwarded_vecinfo(op)
     return vec_reg_size // vecinfo.bytesize
コード例 #9
0
ファイル: vector_ext.py プロジェクト: mozillazg/pypy
    def check_operation(self, state, pack, op):
        i = 0
        infos = [forwarded_vecinfo(o) for o in op.getarglist()]
        arg0 = op.getarg(i)
        while arg0.is_constant() and i < op.numargs():
            i += 1
            arg0 = op.getarg(i)
        vecinfo = forwarded_vecinfo(arg0)
        bytesize = vecinfo.bytesize
        datatype = vecinfo.datatype

        for arg in op.getarglist():
            if arg.is_constant():
                continue
            curvecinfo = forwarded_vecinfo(arg)
            if curvecinfo.bytesize != bytesize:
                debug_print("op match size first type failed")
                raise NotAVectorizeableLoop
            if curvecinfo.datatype != datatype:
                debug_print("op match size first type failed (datatype)")
                raise NotAVectorizeableLoop
        return None
コード例 #10
0
    def check_operation(self, state, pack, op):
        i = 0
        infos = [forwarded_vecinfo(o) for o in op.getarglist()]
        arg0 = op.getarg(i)
        while arg0.is_constant() and i < op.numargs():
            i += 1
            arg0 = op.getarg(i)
        vecinfo = forwarded_vecinfo(arg0)
        bytesize = vecinfo.bytesize
        datatype = vecinfo.datatype

        for arg in op.getarglist():
            if arg.is_constant():
                continue
            curvecinfo = forwarded_vecinfo(arg)
            if curvecinfo.bytesize != bytesize:
                debug_print("op match size first type failed")
                raise NotAVectorizeableLoop
            if curvecinfo.datatype != datatype:
                debug_print("op match size first type failed (datatype)")
                raise NotAVectorizeableLoop
        return None
コード例 #11
0
ファイル: vector_ext.py プロジェクト: mozillazg/pypy
 def must_crop_vector(self, op, index):
     restrict = self.argument_restrictions[index]
     vecinfo = forwarded_vecinfo(op.getarg(index))
     size = vecinfo.bytesize
     newsize = self.crop_to_size(op, index)
     return not restrict.any_size() and newsize != size
コード例 #12
0
ファイル: vector_ext.py プロジェクト: mozillazg/pypy
 def must_crop_vector(self, op, index):
     vecinfo = forwarded_vecinfo(op.getarg(index))
     bytesize = vecinfo.bytesize
     return self.crop_to_size(op, index) != bytesize
コード例 #13
0
ファイル: vector_ext.py プロジェクト: mozillazg/pypy
 def opcount_filling_vector_register(self, op, vec_reg_size):
     arg = op.getarg(0)
     vecinfo = forwarded_vecinfo(arg)
     return vec_reg_size // vecinfo.bytesize
コード例 #14
0
 def must_crop_vector(self, op, index):
     restrict = self.argument_restrictions[index]
     vecinfo = forwarded_vecinfo(op.getarg(index))
     size = vecinfo.bytesize
     newsize = self.crop_to_size(op, index)
     return not restrict.any_size() and newsize != size
コード例 #15
0
 def must_crop_vector(self, op, index):
     vecinfo = forwarded_vecinfo(op.getarg(index))
     bytesize = vecinfo.bytesize
     return self.crop_to_size(op, index) != bytesize
コード例 #16
0
 def opcount_filling_vector_register(self, op, vec_reg_size):
     arg = op.getarg(0)
     vecinfo = forwarded_vecinfo(arg)
     return vec_reg_size // vecinfo.bytesize